Squashed 'third_party/ceres/' changes from e51e9b46f..399cda773

399cda773 Update build documentation to reflect detection of Eigen via config mode
bb127272f Fix typos.
a0ec5c32a Update version history for 2.0.0RC2
3f6d27367 Unify symbol visibility configuration for all compilers
29c2912ee Unbreak the bazel build some more
bf47e1a36 Fix the Bazel build.
600e8c529 fix minor typos
bdcdcc78a update docs for changed cmake usage
3f69e5b36 Corrections from William Rucklidge
8bfdb02fb Rewrite uses of VLOG_IF and LOG_IF.
d1b35ffc1 Corrections from William Rucklidge
f34e80e91 Add dividers between licenses.
65c397dae Fix formatting
f63b1fea9 Add the MIT license text corresponding to the libmv derived files.
542613c13 minor formatting fix for trust_region_minimizer.cc
6d9e9843d Remove inclusion of ceres/eigen.h
eafeca5dc Fix a logging bug in TrustRegionMinimizer.
1fd0be916 Fix default initialisation of IterationCallback::cost
137bbe845 add info about clang-format to contributing docs
d3f66d77f fix formatting generated files (best effort)
a9c7361c8 minor formatting fix (wrongly updated in earlier commit)
7b8f675bf fix formatting for (non-generated) internal source files
921368ce3 Fix a number of typos in covariance.h
7b6b2491c fix formatting for examples
82275d8a4 some fixes for Linux and macOS install docs
9d762d74f fix formatting for public header files
c76478c48 gitignore *.pyc
4e69a475c Fix potential for mismatched release/debug TBB libraries
8e1d8e32a A number of small changes.
368a738e5 AutoDiffCostFunction: optional ownership
8cbd721c1 Add erf and erfc to jet.h, including tests in jet_test.cc
31366cff2 Benchmarks for dynamic autodiff.
29fb08aea Use CMAKE_PREFIX_PATH to pass Homebrew install location
242c703b5 Minor fixes to the documentation
79bbf9510 Add changelog for 2.0.0
41d05f13d Fix lint errors in evaluation_callback_test.cc
4b67903c1 Remove unused variables from problem_test.cc
10449fc36 Add Apache license to the LICENSE file for FixedArray
8c3ecec6d Fix some minor errors in IterationCallback docs
7d3ffcb42 Remove forced CONFIG from find_package(Eigen3)
a029fc0f9 Use latest FindTBB.cmake from VTK project
aa1abbc57 Replace use of GFLAGS_LIBRARIES with export gflags target
db2af1be8 Add Problem::EvaluateResidualBlockAssumingParametersUnchanged
ab4ed32cd Replace NULL with nullptr in the documentation.
ee280e27a Allow SubsetParameterization to accept an empty vector of constant parameters.
4b8c731d8 Fix a bug in DynamicAutoDiffCostFunction
5cb5b35a9 Fixed incorrect argument name in RotationMatrixToQuaternion()
e39d9ed1d Add a missing term and remove a superfluous word
27cab77b6 Reformulate some sentences
8ac6655ce Fix documentation formatting issues
7ef83e075 Update minimum required C++ version for Ceres to C++14
1d75e7568 Improve documentation for LocalParameterization
763398ca4 Update the section on Preconditioners
a614f788a Call EvaluationCallback before evaluating the fixed cost.
70308f7bb Simplify documentation generation.
e886d7e65 Reduce the number of minimizer iterations in evaluation_callback_test.cc
9483e6f2f Simplify DynamicCompressedRowJacobianWriter::Write
323cc55bb Update the version in package.xml to 2.0.0.
303b078b5 Fix few typos and alter a NULL to nullptr.
cca93fed6 Bypass Ceres' FindGlog.cmake in CeresConfig.cmake if possible
77fc1d0fc Use build_depend for private dependencies in Catkin package.xml
a09682f00 Fix MSVC version check to support use of clang-cl front-end
b70687fcc Add namespace qualified Ceres::ceres CMake target
99efa54bd Replace type aliases deprecated/removed in C++17/C++20 from FixedArray
adb973e4a NULL -> nullptr
27b717951 Respect FIND_QUIETLY flag in cmake config file
646959ef1 Do not export class template LineParameterization
1f128d070 Change the type of parameter index/offset to match their getter/setter
072c8f070 Initialize integer variables with integer instead of double
8c36bcc81 Use inline & -inlinehint-threshold in auto-diff benchmarks
57cf20aa5 static const -> static constexpr where we can.
40b27482a Add std::numeric_limit specialization for Jets
e751d6e4f Remove AutodiffCodegen
e9eb76f8e Remove AutodiffCodegen CMake integration
9435e08a7 More clang-tidy and wjr@ comment fixes
d93fac4b7 Remove AutodiffCodegen Tests
2281c6ed2 Fixes for comments from William Rucklidge
d797a87a4 Use Ridders' method in GradientChecker.
41675682d Fix a MSVC type deduction bug in ComputeHouseholderVector
947ec0c1f Remove AutodiffCodegen autodiff benchmarks
27183d661 Allow LocalParameterizations to have zero local size.
7ac7d79dc Remove HelloWorldCodegen example
8c8738bf8 Add photometric and relative-pose residuals to autodiff benchmarks
9f7fb66d6 Add a constant cost function to the autodiff benchmarks
ab0d373e4 Fix a comment in autodiff.h
27bb99714 Change SVD algorithm in covariance computation.
84fdac38e Add const to GetCovarianceMatrix*
6bde61d6b Add line local parameterization.
2c1c0932e Update documentation in autodiff.h
8904fa488 Inline Jet initialization in Autodiff
18a464d4e Remove an errant CR from local_parameterization.cc
5c85f2179 Use ArraySelector in Autodiff
80477ff07 Add class ArraySelector
e7a30359e Pass kNumResiduals to Autodiff
f339d71dd Refactor the automatic differentiation benchmarks.
d37b4cb15 Fix some include headers in codegen/test_utils.cc/h
550766e6d Add Autodiff Brdf Benchmark
8da9876e7 Add more autodiff benchmarks
6da364713 Fix Tukey loss function
cf4185c4e Add Codegen BA Benchmark
75dd30fae Simplify GenerateCodeForFunctor
9049688c6 Default Initialize ExpressionRef to Zero
bf1aff2f0 Fix 3+ nested Jet constructor
92d6541c7 Move Codegen files into codegen/ directory
8e962f37d Add Autodiff Codegen Tests
13c7a22ce Codegen Optimizer API
90799e29e Fix install and unnecessary string copy
032d5844c AutoDiff Code Generation - CMake Integration
d82de91b8 Add ExpressionGraph::Erase(ExpressionId)
c8e35e19f Add namespaces to generated functions and constants
75e575cae Fix use of incomplete type in defaulted Problem methods
8def19616 Remove ExpressionRef Move Constructor
f26f95410 Fix windows MSVC build.
fdf9cfd32 Add functions to find the matching ELSE, ENDIF expressions
678c05b28 Fix invert PSD matrix.
a384a7e96 Remove not used using declaration
a60136b7a Add COMMENT ExpressionType
f212c9295 Let Problem::SetParameterization be called more than once.
a3696835b use CMake function to create CeresConfigVersion
67fcff918 Make Problem movable.
19728e72d Add documentation for Problem::IsParameterBlockConstant
ba6e5fb4a Make the custom uninstall target optional
8547cbd55 Make EventLogger more efficient.
edb8322bd Update the minimum required version of Eigen to 3.3.
aa6ef417f Specify Eigen3_DIR in iOS and Android Travis CI builds
4655f2549 Use find_package() instead of find_dependency() in CeresConfig.cmake
a548766d1 Use glfags target
33dd469a5 Use Eigen3::Eigen target
47e784bb4 NULL-jacobians are handled correctly in generated autodiff code
edd54b83e Update Jet.h and rotation.h to use the new IF/ELSE macros
848c1f90c Update return type in code generator and add tests for logical functions
5010421bb Add the expression return type as a member to Expression
f4dc670ee Improve testing of the codegen system
572ec4a5a Rework Expression creation and insertion
c7337154e Disable the code generation module by default
7fa0f3db4 Explicitly state PUBLIC/PRIVATE when linking
4362a2169 Run clang-format on the public headers. Also update copyright year.
c56702aac Fix installation of codegen headers
0d03e74dc Fix the include in the autodiff codegen example
d16026440 Autodiff Codegen Part 4: Public API
d1703db45 Moved AutoDiffCodeGen macros to a separate (public) header
5ce6c063d Fix ExpressionRef copy constructor and add a move constructor
a90b5a12c Pass ExpressionRef by const reference instead of by value
ea057678c Remove MakeFunctionCall() and add test for Ternary
1084c5460 Quote all configure-expanded paths
3d756b07c Test Expressions with 'insert' instead of a macro
486d81812 Add ExpressionGraph::InsertExpression
3831a1dd3 Expression and ExpressionGraph comparison
9bb1dcb84 Remove definition of ExpressionRef::ExpressionRef(double&);
5be2e4883 Autodiff Codegen Part 3: CodeGenerator
6cd633043 Remove unused ExpressionTypes
7d0d69a4d Fix ExpressionRef
6ba8c57d2 Fix expression_test IsArithmetic
2b494cfb3 Update Travis CI to Bionic & Xcode 11.2
a3dde6877 Require Xcode >= 11.2 on macOS 10.15 (Catalina)
6fd4f072d Autodiff Codegen Part 2: Conditionals
52d6477a4 Detect and disable -fstack-check on macOS 10.15 with Xcode 11
46ca461b7 Fix `gradient_check_relative_precision` docs typo
4247d420f Autodiff Codegen Part 1: Expressions
ba62397d8 Run clang-format on jet.h
667062dcc Introduce BlockSparseMatrixData
17becf461 Remove a CHECK failure from covariance_impl.cc
d7f428e5c Add a missing cast in rotation.h
ea4d66e7e clang-tidy fixes.
be15b842a Integrate the SchurEliminatorForOneFBlock for the case <2,3,6>
087b28f1b Remove use of SetUsage as it creates compilation problems.
573046d7f Protect declarations of lapack functions under CERES_NO_LAPACK
71d638ef3 Add a specialized schur eliminator.
2ffddaccf Use override & final instead of just using virtual.
e4577dd6d Use override instead of virtual for subclasses.
3e5db5bc2 Fixing documentation typo.
82d325b73 Avoid memory allocations in Accelerate Sparse[Refactor/Solve]().
f66b51382 Fix some clang-tidy warnings.
0428e2dd0 Fix missing #include of <memory>
487c1aa51 Expose SubsetPreconditioner in the API
bf709ecac Move EvaluationCallback from Solver::Options to Problem::Options.
059bcb7f8 Drop ROS dependency on catkin
c4dbc927d Default to any other sparse libraries over Accelerate
db1f5b57a Allow some methods in Problem to use const double*.
a60c14525 Explicitly delete the copy constructor and copy assignment operator
084042c25 Lint changes from William Rucklidge
93d869020 Use selfAdjoingView<Upper> in InvertPSDMatrix.
a0cd0854a Speed up InvertPSDMatrix
7b53262b7 Allow Solver::Options::max_num_line_search_step_size_iterations = 0.
3e2cdca54 Make LineSearchMinizer work correctly with negative valued functions.
3ff12a878 Fix a clang-tidy warning in problem_test.cc
57441fe90 Fix two bugs.
1b852c57e Add Problem::EvaluateResidualBlock.
54ba6c27b Fix missing declaration warnings in Ceres code
fac46d50e Modernize ProductParameterization.
53dc6213f Add some missing string-to-enum-to-string convertors.
c0aa9a263 Add checks in rotation.h for inplace operations.
0f57fa82d Update Bazel WORKSPACE for newest Bazel
f8e5fba7b TripletSparseMatrix: guard against self-assignment
939253c20 Fix Eigen alignment issues.
bf67daf79 Add the missing <array> header to fixed_array.h
25e1cdbb6 Switch to FixedArray implementation from abseil.
d467a627b IdentityTransformation -> IdentityParameterization
eaec6a9d0 Fix more typos in CostFunctionToFunctor documentation.
99b5aa4aa Fix typos in CostFunctionToFunctor documentation.
ee7e2cb3c Set Homebrew paths via HINTS not CMAKE_PREFIX_PATH
4f8a01853 Revert "Fix custom Eigen on macos (EIGEN_INCLUDE_DIR_HINTS)"
e6c5c7226 Fix custom Eigen on macos (EIGEN_INCLUDE_DIR_HINTS)
5a56d522e Add the 3,3,3 template specialization.
df5c23116 Reorder initializer list to make -Wreorder happy
0fcfdb0b4 Fix the build breakage caused by the last commit.
9b9e9f0dc Reduce machoness of macro definition in cost_functor_to_function_test.cc
21d40daa0 Remove UTF-8 chars
9350e57a4 Enable optional use of sanitizers
0456edffb Update Travis CI Linux distro to 16.04 (Xenial)
bef0dfe35 Fix a typo in cubic_interpolation.h
056ba9bb1 Add AutoDiffFirstOrderFunction
6e527392d Update googletest/googlemock to db9b85e2.
1b2940749 Clarify documentation of BiCubicInterpolator::Evaluate for out-of-bounds values

Change-Id: Id61dd832e8fbe286deb0799aa1399d4017031dae
git-subtree-dir: third_party/ceres
git-subtree-split: 399cda773035d99eaf1f4a129a666b3c4df9d1b1
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index 5bbe2bd..6dc7262 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -30,7 +30,7 @@
 
 # Avoid 'xxx.cc has no symbols' warnings from source files which are 'empty'
 # when their enclosing #ifdefs are disabled.
-if (CERES_THREADING_MODEL STREQUAL "CXX11_THREADS")
+if (CERES_THREADING_MODEL STREQUAL "CXX_THREADS")
   set(CERES_PARALLEL_FOR_SRC parallel_for_cxx.cc thread_pool.cc)
 elseif (CERES_THREADING_MODEL STREQUAL "OPENMP")
   set(CERES_PARALLEL_FOR_SRC parallel_for_openmp.cc)
@@ -176,13 +176,13 @@
 
 if (NOT MINIGLOG AND GLOG_FOUND)
   list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES ${GLOG_LIBRARIES})
-  if (GFLAGS_FOUND)
+  if (gflags_FOUND)
     # If glog & gflags are both found, we assume that glog was built with
     # gflags, as it is awkward to perform a try_compile() to verify this
     # when gflags is an imported target (as it is in newer versions).
     # As glog #includes gflags/gflags.h in glog/logging.h if compiled with
     # gflags, it is thus a public dependency for Ceres in this case.
-    list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES ${GFLAGS_LIBRARIES})
+    list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES gflags)
   endif()
 endif (NOT MINIGLOG AND GLOG_FOUND)
 
@@ -219,10 +219,37 @@
   list(APPEND CERES_LIBRARY_SOURCE miniglog/glog/logging.cc)
 endif (MINIGLOG)
 
+# Ceres C++ compiler flags can be too strict for an external library code
+# which we do not maintain.
+include(CheckCXXCompilerFlag)
+check_cxx_compiler_flag("-Wno-missing-declarations"
+                        CHECK_CXX_FLAG_Wno_missing_declarations)
+if (CHECK_CXX_FLAG_Wno_missing_declarations)
+  set_property(SOURCE gmock_gtest_all.cc
+               APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-missing-declarations")
+endif()
+
 add_library(ceres ${CERES_LIBRARY_SOURCE})
 set_target_properties(ceres PROPERTIES
   VERSION ${CERES_VERSION}
   SOVERSION ${CERES_VERSION_MAJOR})
+if (BUILD_SHARED_LIBS)
+  set_target_properties(ceres PROPERTIES
+    # Set the default symbol visibility to hidden to unify the behavior among
+    # the various compilers and to get smaller binaries
+    C_VISIBILITY_PRESET hidden
+    CXX_VISIBILITY_PRESET hidden)
+endif()
+
+# When building as a shared libarary with testing enabled, we need to export
+# internal symbols needed by the unit tests
+if (BUILD_TESTING)
+  target_compile_definitions(ceres
+    PUBLIC
+      CERES_EXPORT_INTERNAL_SYMBOLS
+    )
+endif()
+
 
 # The ability to specify a minimum language version via cxx_std_[11,14,17]
 # requires CMake >= 3.8.  Prior to that we have to specify the compiler features
@@ -250,8 +277,8 @@
   # When building a shared library, mark all external libraries as
   # PRIVATE so they don't show up as a dependency.
   target_link_libraries(ceres
-        LINK_PUBLIC ${CERES_LIBRARY_PUBLIC_DEPENDENCIES}
-        LINK_PRIVATE ${CERES_LIBRARY_PRIVATE_DEPENDENCIES})
+        PUBLIC ${CERES_LIBRARY_PUBLIC_DEPENDENCIES}
+        PRIVATE ${CERES_LIBRARY_PRIVATE_DEPENDENCIES})
 else (BUILD_SHARED_LIBS)
   # When building a static library, all external libraries are
   # PUBLIC(default) since the user needs to link to them.
@@ -259,7 +286,7 @@
   set(CERES_LIBRARY_DEPENDENCIES
         ${CERES_LIBRARY_PUBLIC_DEPENDENCIES}
         ${CERES_LIBRARY_PRIVATE_DEPENDENCIES})
-  target_link_libraries(ceres ${CERES_LIBRARY_DEPENDENCIES})
+  target_link_libraries(ceres PUBLIC ${CERES_LIBRARY_DEPENDENCIES})
 endif (BUILD_SHARED_LIBS)
 
 # Add the Ceres headers to its target.
@@ -281,7 +308,7 @@
 # warnings around the #include statments for Eigen headers across all GCC/Clang
 # versions, we tell CMake to treat Eigen headers as system headers.  This
 # results in all compiler warnings from them being suppressed.
-target_include_directories(ceres SYSTEM PUBLIC ${EIGEN_INCLUDE_DIRS})
+target_link_libraries(ceres PUBLIC Eigen3::Eigen)
 
 # Gather the list of public & private include locations for all enabled optional
 # dependencies to be added to the Ceres target.
@@ -319,12 +346,6 @@
   list(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES_INCLUDE_DIRS
     ${AccelerateSparse_INCLUDE_DIRS})
 endif()
-if (GFLAGS AND NOT FOUND_INSTALLED_GFLAGS_CMAKE_CONFIGURATION)
-  # Only append gflags include directories if the gflags found was not a CMake
-  # exported target that already includes them.
-  list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES_INCLUDE_DIRS
-    ${GFLAGS_INCLUDE_DIRS})
-endif()
 # Add include locations for optional dependencies to the Ceres target without
 # duplication.
 list(REMOVE_DUPLICATES CERES_LIBRARY_PRIVATE_DEPENDENCIES_INCLUDE_DIRS)
@@ -342,6 +363,9 @@
         LIBRARY DESTINATION lib${LIB_SUFFIX}
         ARCHIVE DESTINATION lib${LIB_SUFFIX})
 
+# Create a local alias target that matches the expected installed target.
+add_library(Ceres::ceres ALIAS ceres)
+
 if (BUILD_TESTING AND GFLAGS)
   add_library(gtest gmock_gtest_all.cc gmock_main.cc)
   target_include_directories(gtest PUBLIC ${Ceres_SOURCE_DIR}/internal/ceres)
@@ -360,11 +384,11 @@
   if (MINIGLOG)
     # When using miniglog, it is compiled into Ceres, thus Ceres becomes
     # the library against which other libraries should link for logging.
-    target_link_libraries(gtest ${GFLAGS_LIBRARIES} ceres)
-    target_link_libraries(test_util ceres gtest)
+    target_link_libraries(gtest PUBLIC gflags Ceres::ceres)
+    target_link_libraries(test_util PUBLIC Ceres::ceres gtest)
   else (MINIGLOG)
-    target_link_libraries(gtest ${GFLAGS_LIBRARIES} ${GLOG_LIBRARIES})
-    target_link_libraries(test_util ceres gtest ${GLOG_LIBRARIES})
+    target_link_libraries(gtest PUBLIC gflags ${GLOG_LIBRARIES})
+    target_link_libraries(test_util PUBLIC Ceres::ceres gtest ${GLOG_LIBRARIES})
   endif (MINIGLOG)
 
   macro (CERES_TEST NAME)
@@ -378,7 +402,7 @@
              ${Ceres_SOURCE_DIR}/internal/ceres
              ${CERES_LIBRARY_PRIVATE_DEPENDENCIES_INCLUDE_DIRS})
 
-    target_link_libraries(${NAME}_test test_util ceres gtest)
+    target_link_libraries(${NAME}_test PUBLIC test_util Ceres::ceres gtest)
     if (BUILD_SHARED_LIBS)
       # Define gtest-specific shared library flags for linking.
       append_target_property(${NAME}_test COMPILE_DEFINITIONS
@@ -391,7 +415,9 @@
   endmacro (CERES_TEST)
 
   ceres_test(array_utils)
+  ceres_test(array_selector)
   ceres_test(autodiff)
+  ceres_test(autodiff_first_order_function)
   ceres_test(autodiff_cost_function)
   ceres_test(autodiff_local_parameterization)
   ceres_test(block_jacobi_preconditioner)
@@ -421,6 +447,7 @@
   ceres_test(dynamic_sparsity)
   ceres_test(evaluation_callback)
   ceres_test(evaluator)
+  ceres_test(fixed_array)
   ceres_test(gradient_checker)
   ceres_test(gradient_checking_cost_function)
   ceres_test(gradient_problem)
@@ -431,7 +458,6 @@
   ceres_test(implicit_schur_complement)
   ceres_test(inner_product_computer)
   ceres_test(invert_psd_matrix)
-  ceres_test(integer_sequence)
   ceres_test(integer_sequence_algorithm)
   ceres_test(is_close)
   ceres_test(iterative_refiner)
@@ -483,19 +509,26 @@
 endif (BUILD_TESTING AND GFLAGS)
 
 macro(add_dependencies_to_benchmark BENCHMARK_TARGET)
-  target_link_libraries(${BENCHMARK_TARGET} ceres benchmark::benchmark)
+  target_link_libraries(${BENCHMARK_TARGET} PUBLIC Ceres::ceres benchmark::benchmark)
   target_include_directories(${BENCHMARK_TARGET} PUBLIC
                              ${Ceres_SOURCE_DIR}/internal
+                             ${Ceres_SOURCE_DIR}/internal/ceres
                              ${CERES_LIBRARY_PRIVATE_DEPENDENCIES_INCLUDE_DIRS})
 endmacro()
 
 if (BUILD_BENCHMARKS)
-  add_executable(autodiff_cost_function_benchmark autodiff_cost_function_benchmark.cc)
-  add_dependencies_to_benchmark(autodiff_cost_function_benchmark)
-
   add_executable(small_blas_gemv_benchmark small_blas_gemv_benchmark.cc)
   add_dependencies_to_benchmark(small_blas_gemv_benchmark)
 
   add_executable(small_blas_gemm_benchmark small_blas_gemm_benchmark.cc)
   add_dependencies_to_benchmark(small_blas_gemm_benchmark)
+
+  add_executable(invert_psd_matrix_benchmark invert_psd_matrix_benchmark.cc)
+  add_dependencies_to_benchmark(invert_psd_matrix_benchmark)
+
+  add_executable(schur_eliminator_benchmark schur_eliminator_benchmark.cc)
+  add_dependencies_to_benchmark(schur_eliminator_benchmark)
+
+  add_subdirectory(autodiff_benchmarks)
 endif (BUILD_BENCHMARKS)
+
diff --git a/internal/ceres/accelerate_sparse.cc b/internal/ceres/accelerate_sparse.cc
index dc02986..d2b642b 100644
--- a/internal/ceres/accelerate_sparse.cc
+++ b/internal/ceres/accelerate_sparse.cc
@@ -33,22 +33,24 @@
 
 #ifndef CERES_NO_ACCELERATE_SPARSE
 
-#include "ceres/accelerate_sparse.h"
-
 #include <algorithm>
 #include <string>
 #include <vector>
 
+#include "ceres/accelerate_sparse.h"
 #include "ceres/compressed_col_sparse_matrix_utils.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "glog/logging.h"
 
-#define CASESTR(x) case x: return #x
+#define CASESTR(x) \
+  case x:          \
+    return #x
 
 namespace ceres {
 namespace internal {
 
+namespace {
 const char* SparseStatusToString(SparseStatus_t status) {
   switch (status) {
     CASESTR(SparseStatusOK);
@@ -61,14 +63,46 @@
       return "UKNOWN";
   }
 }
+}  // namespace.
 
-template<typename Scalar>
-void AccelerateSparse<Scalar>::Solve(NumericFactorization* numeric_factor,
-                                     DenseVector* rhs_and_solution) {
-  SparseSolve(*numeric_factor, *rhs_and_solution);
+// Resizes workspace as required to contain at least required_size bytes
+// aligned to kAccelerateRequiredAlignment and returns a pointer to the
+// aligned start.
+void* ResizeForAccelerateAlignment(const size_t required_size,
+                                   std::vector<uint8_t>* workspace) {
+  // As per the Accelerate documentation, all workspace memory passed to the
+  // sparse solver functions must be 16-byte aligned.
+  constexpr int kAccelerateRequiredAlignment = 16;
+  // Although malloc() on macOS should always be 16-byte aligned, it is unclear
+  // if this holds for new(), or on other Apple OSs (phoneOS, watchOS etc).
+  // As such we assume it is not and use std::align() to create a (potentially
+  // offset) 16-byte aligned sub-buffer of the specified size within workspace.
+  workspace->resize(required_size + kAccelerateRequiredAlignment);
+  size_t size_from_aligned_start = workspace->size();
+  void* aligned_solve_workspace_start =
+      reinterpret_cast<void*>(workspace->data());
+  aligned_solve_workspace_start = std::align(kAccelerateRequiredAlignment,
+                                             required_size,
+                                             aligned_solve_workspace_start,
+                                             size_from_aligned_start);
+  CHECK(aligned_solve_workspace_start != nullptr)
+      << "required_size: " << required_size
+      << ", workspace size: " << workspace->size();
+  return aligned_solve_workspace_start;
 }
 
-template<typename Scalar>
+template <typename Scalar>
+void AccelerateSparse<Scalar>::Solve(NumericFactorization* numeric_factor,
+                                     DenseVector* rhs_and_solution) {
+  // From SparseSolve() documentation in Solve.h
+  const int required_size = numeric_factor->solveWorkspaceRequiredStatic +
+                            numeric_factor->solveWorkspaceRequiredPerRHS;
+  SparseSolve(*numeric_factor,
+              *rhs_and_solution,
+              ResizeForAccelerateAlignment(required_size, &solve_workspace_));
+}
+
+template <typename Scalar>
 typename AccelerateSparse<Scalar>::ASSparseMatrix
 AccelerateSparse<Scalar>::CreateSparseMatrixTransposeView(
     CompressedRowSparseMatrix* A) {
@@ -78,7 +112,7 @@
   //
   // Accelerate's columnStarts is a long*, not an int*.  These types might be
   // different (e.g. ARM on iOS) so always make a copy.
-  column_starts_.resize(A->num_rows() +1); // +1 for final column length.
+  column_starts_.resize(A->num_rows() + 1);  // +1 for final column length.
   std::copy_n(A->rows(), column_starts_.size(), &column_starts_[0]);
 
   ASSparseMatrix At;
@@ -102,23 +136,31 @@
   return At;
 }
 
-template<typename Scalar>
+template <typename Scalar>
 typename AccelerateSparse<Scalar>::SymbolicFactorization
 AccelerateSparse<Scalar>::AnalyzeCholesky(ASSparseMatrix* A) {
   return SparseFactor(SparseFactorizationCholesky, A->structure);
 }
 
-template<typename Scalar>
+template <typename Scalar>
 typename AccelerateSparse<Scalar>::NumericFactorization
 AccelerateSparse<Scalar>::Cholesky(ASSparseMatrix* A,
                                    SymbolicFactorization* symbolic_factor) {
   return SparseFactor(*symbolic_factor, *A);
 }
 
-template<typename Scalar>
+template <typename Scalar>
 void AccelerateSparse<Scalar>::Cholesky(ASSparseMatrix* A,
                                         NumericFactorization* numeric_factor) {
-  return SparseRefactor(*A, numeric_factor);
+  // From SparseRefactor() documentation in Solve.h
+  const int required_size =
+      std::is_same<Scalar, double>::value
+          ? numeric_factor->symbolicFactorization.workspaceSize_Double
+          : numeric_factor->symbolicFactorization.workspaceSize_Float;
+  return SparseRefactor(
+      *A,
+      numeric_factor,
+      ResizeForAccelerateAlignment(required_size, &factorization_workspace_));
 }
 
 // Instantiate only for the specific template types required/supported s/t the
@@ -126,34 +168,33 @@
 template class AccelerateSparse<double>;
 template class AccelerateSparse<float>;
 
-template<typename Scalar>
-std::unique_ptr<SparseCholesky>
-AppleAccelerateCholesky<Scalar>::Create(OrderingType ordering_type) {
+template <typename Scalar>
+std::unique_ptr<SparseCholesky> AppleAccelerateCholesky<Scalar>::Create(
+    OrderingType ordering_type) {
   return std::unique_ptr<SparseCholesky>(
       new AppleAccelerateCholesky<Scalar>(ordering_type));
 }
 
-template<typename Scalar>
+template <typename Scalar>
 AppleAccelerateCholesky<Scalar>::AppleAccelerateCholesky(
     const OrderingType ordering_type)
     : ordering_type_(ordering_type) {}
 
-template<typename Scalar>
+template <typename Scalar>
 AppleAccelerateCholesky<Scalar>::~AppleAccelerateCholesky() {
   FreeSymbolicFactorization();
   FreeNumericFactorization();
 }
 
-template<typename Scalar>
+template <typename Scalar>
 CompressedRowSparseMatrix::StorageType
 AppleAccelerateCholesky<Scalar>::StorageType() const {
   return CompressedRowSparseMatrix::LOWER_TRIANGULAR;
 }
 
-template<typename Scalar>
-LinearSolverTerminationType
-AppleAccelerateCholesky<Scalar>::Factorize(CompressedRowSparseMatrix* lhs,
-                                           std::string* message) {
+template <typename Scalar>
+LinearSolverTerminationType AppleAccelerateCholesky<Scalar>::Factorize(
+    CompressedRowSparseMatrix* lhs, std::string* message) {
   CHECK_EQ(lhs->storage_type(), StorageType());
   if (lhs == NULL) {
     *message = "Failure: Input lhs is NULL.";
@@ -194,11 +235,9 @@
   return LINEAR_SOLVER_SUCCESS;
 }
 
-template<typename Scalar>
-LinearSolverTerminationType
-AppleAccelerateCholesky<Scalar>::Solve(const double* rhs,
-                                       double* solution,
-                                       std::string* message) {
+template <typename Scalar>
+LinearSolverTerminationType AppleAccelerateCholesky<Scalar>::Solve(
+    const double* rhs, double* solution, std::string* message) {
   CHECK_EQ(numeric_factor_->status, SparseStatusOK)
       << "Solve called without a call to Factorize first ("
       << SparseStatusToString(numeric_factor_->status) << ").";
@@ -222,7 +261,7 @@
   return LINEAR_SOLVER_SUCCESS;
 }
 
-template<typename Scalar>
+template <typename Scalar>
 void AppleAccelerateCholesky<Scalar>::FreeSymbolicFactorization() {
   if (symbolic_factor_) {
     SparseCleanup(*symbolic_factor_);
@@ -230,7 +269,7 @@
   }
 }
 
-template<typename Scalar>
+template <typename Scalar>
 void AppleAccelerateCholesky<Scalar>::FreeNumericFactorization() {
   if (numeric_factor_) {
     SparseCleanup(*numeric_factor_);
@@ -243,7 +282,7 @@
 template class AppleAccelerateCholesky<double>;
 template class AppleAccelerateCholesky<float>;
 
-}
-}
+}  // namespace internal
+}  // namespace ceres
 
 #endif  // CERES_NO_ACCELERATE_SPARSE
diff --git a/internal/ceres/accelerate_sparse.h b/internal/ceres/accelerate_sparse.h
index b849a80..e53758d 100644
--- a/internal/ceres/accelerate_sparse.h
+++ b/internal/ceres/accelerate_sparse.h
@@ -40,9 +40,9 @@
 #include <string>
 #include <vector>
 
+#include "Accelerate.h"
 #include "ceres/linear_solver.h"
 #include "ceres/sparse_cholesky.h"
-#include "Accelerate.h"
 
 namespace ceres {
 namespace internal {
@@ -50,11 +50,10 @@
 class CompressedRowSparseMatrix;
 class TripletSparseMatrix;
 
-template<typename Scalar>
-struct SparseTypesTrait {
-};
+template <typename Scalar>
+struct SparseTypesTrait {};
 
-template<>
+template <>
 struct SparseTypesTrait<double> {
   typedef DenseVector_Double DenseVector;
   typedef SparseMatrix_Double SparseMatrix;
@@ -62,7 +61,7 @@
   typedef SparseOpaqueFactorization_Double NumericFactorization;
 };
 
-template<>
+template <>
 struct SparseTypesTrait<float> {
   typedef DenseVector_Float DenseVector;
   typedef SparseMatrix_Float SparseMatrix;
@@ -70,14 +69,16 @@
   typedef SparseOpaqueFactorization_Float NumericFactorization;
 };
 
-template<typename Scalar>
+template <typename Scalar>
 class AccelerateSparse {
  public:
   using DenseVector = typename SparseTypesTrait<Scalar>::DenseVector;
   // Use ASSparseMatrix to avoid collision with ceres::internal::SparseMatrix.
   using ASSparseMatrix = typename SparseTypesTrait<Scalar>::SparseMatrix;
-  using SymbolicFactorization = typename SparseTypesTrait<Scalar>::SymbolicFactorization;
-  using NumericFactorization = typename SparseTypesTrait<Scalar>::NumericFactorization;
+  using SymbolicFactorization =
+      typename SparseTypesTrait<Scalar>::SymbolicFactorization;
+  using NumericFactorization =
+      typename SparseTypesTrait<Scalar>::NumericFactorization;
 
   // Solves a linear system given its symbolic (reference counted within
   // NumericFactorization) and numeric factorization.
@@ -101,13 +102,15 @@
 
  private:
   std::vector<long> column_starts_;
+  std::vector<uint8_t> solve_workspace_;
+  std::vector<uint8_t> factorization_workspace_;
   // Storage for the values of A if Scalar != double (necessitating a copy).
   Eigen::Matrix<Scalar, Eigen::Dynamic, 1> values_;
 };
 
 // An implementation of SparseCholesky interface using Apple's Accelerate
 // framework.
-template<typename Scalar>
+template <typename Scalar>
 class AppleAccelerateCholesky : public SparseCholesky {
  public:
   // Factory
@@ -115,12 +118,12 @@
 
   // SparseCholesky interface.
   virtual ~AppleAccelerateCholesky();
-  virtual CompressedRowSparseMatrix::StorageType StorageType() const;
-  virtual LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
-                                                std::string* message);
-  virtual LinearSolverTerminationType Solve(const double* rhs,
-                                            double* solution,
-                                            std::string* message);
+  CompressedRowSparseMatrix::StorageType StorageType() const;
+  LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
+                                        std::string* message) final;
+  LinearSolverTerminationType Solve(const double* rhs,
+                                    double* solution,
+                                    std::string* message) final;
 
  private:
   AppleAccelerateCholesky(const OrderingType ordering_type);
@@ -130,15 +133,15 @@
   const OrderingType ordering_type_;
   AccelerateSparse<Scalar> as_;
   std::unique_ptr<typename AccelerateSparse<Scalar>::SymbolicFactorization>
-  symbolic_factor_;
+      symbolic_factor_;
   std::unique_ptr<typename AccelerateSparse<Scalar>::NumericFactorization>
-  numeric_factor_;
+      numeric_factor_;
   // Copy of rhs/solution if Scalar != double (necessitating a copy).
   Eigen::Matrix<Scalar, Eigen::Dynamic, 1> scalar_rhs_and_solution_;
 };
 
-}
-}
+}  // namespace internal
+}  // namespace ceres
 
 #endif  // CERES_NO_ACCELERATE_SPARSE
 
diff --git a/internal/ceres/array_selector_test.cc b/internal/ceres/array_selector_test.cc
new file mode 100644
index 0000000..f7fef3c
--- /dev/null
+++ b/internal/ceres/array_selector_test.cc
@@ -0,0 +1,79 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2020 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// 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: darius.rueckert@fau.de (Darius Rueckert)
+//
+
+#include "ceres/internal/array_selector.h"
+
+#include "gtest/gtest.h"
+
+namespace ceres {
+namespace internal {
+
+// This test only checks, if the correct array implementations are selected. The
+// test for FixedArray is in fixed_array_test.cc. Tests for std::array and
+// std::vector are not included in ceres.
+TEST(ArraySelector, FixedArray) {
+  ArraySelector<int, DYNAMIC, 20> array1(10);
+  static_assert(
+      std::is_base_of<internal::FixedArray<int, 20>, decltype(array1)>::value,
+      "");
+  EXPECT_EQ(array1.size(), 10);
+
+  ArraySelector<int, DYNAMIC, 10> array2(20);
+  static_assert(
+      std::is_base_of<internal::FixedArray<int, 10>, decltype(array2)>::value,
+      "");
+  EXPECT_EQ(array2.size(), 20);
+}
+
+TEST(ArraySelector, Array) {
+  ArraySelector<int, 10, 20> array1(10);
+  static_assert(std::is_base_of<std::array<int, 10>, decltype(array1)>::value,
+                "");
+  EXPECT_EQ(array1.size(), 10);
+
+  ArraySelector<int, 20, 20> array2(20);
+  static_assert(std::is_base_of<std::array<int, 20>, decltype(array2)>::value,
+                "");
+  EXPECT_EQ(array2.size(), 20);
+}
+
+TEST(ArraySelector, Vector) {
+  ArraySelector<int, 20, 10> array1(20);
+  static_assert(std::is_base_of<std::vector<int>, decltype(array1)>::value, "");
+  EXPECT_EQ(array1.size(), 20);
+
+  ArraySelector<int, 1, 0> array2(1);
+  static_assert(std::is_base_of<std::vector<int>, decltype(array2)>::value, "");
+  EXPECT_EQ(array2.size(), 1);
+}
+
+}  // namespace internal
+}  // namespace ceres
diff --git a/internal/ceres/array_utils.cc b/internal/ceres/array_utils.cc
index 32459e6..6bffd84 100644
--- a/internal/ceres/array_utils.cc
+++ b/internal/ceres/array_utils.cc
@@ -35,6 +35,7 @@
 #include <cstddef>
 #include <string>
 #include <vector>
+
 #include "ceres/stringprintf.h"
 #include "ceres/types.h"
 namespace ceres {
@@ -45,7 +46,7 @@
 bool IsArrayValid(const int size, const double* x) {
   if (x != NULL) {
     for (int i = 0; i < size; ++i) {
-      if (!std::isfinite(x[i]) || (x[i] == kImpossibleValue))  {
+      if (!std::isfinite(x[i]) || (x[i] == kImpossibleValue)) {
         return false;
       }
     }
@@ -59,7 +60,7 @@
   }
 
   for (int i = 0; i < size; ++i) {
-    if (!std::isfinite(x[i]) || (x[i] == kImpossibleValue))  {
+    if (!std::isfinite(x[i]) || (x[i] == kImpossibleValue)) {
       return i;
     }
   }
@@ -92,14 +93,13 @@
 void MapValuesToContiguousRange(const int size, int* array) {
   std::vector<int> unique_values(array, array + size);
   std::sort(unique_values.begin(), unique_values.end());
-  unique_values.erase(std::unique(unique_values.begin(),
-                                  unique_values.end()),
+  unique_values.erase(std::unique(unique_values.begin(), unique_values.end()),
                       unique_values.end());
 
   for (int i = 0; i < size; ++i) {
-    array[i] = std::lower_bound(unique_values.begin(),
-                                unique_values.end(),
-                                array[i]) - unique_values.begin();
+    array[i] =
+        std::lower_bound(unique_values.begin(), unique_values.end(), array[i]) -
+        unique_values.begin();
   }
 }
 
diff --git a/internal/ceres/array_utils.h b/internal/ceres/array_utils.h
index 1d55733..68feca5 100644
--- a/internal/ceres/array_utils.h
+++ b/internal/ceres/array_utils.h
@@ -44,6 +44,7 @@
 #define CERES_INTERNAL_ARRAY_UTILS_H_
 
 #include <string>
+
 #include "ceres/internal/port.h"
 
 namespace ceres {
@@ -51,20 +52,22 @@
 
 // Fill the array x with an impossible value that the user code is
 // never expected to compute.
-void InvalidateArray(int size, double* x);
+CERES_EXPORT_INTERNAL void InvalidateArray(int size, double* x);
 
 // Check if all the entries of the array x are valid, i.e. all the
 // values in the array should be finite and none of them should be
 // equal to the "impossible" value used by InvalidateArray.
-bool IsArrayValid(int size, const double* x);
+CERES_EXPORT_INTERNAL bool IsArrayValid(int size, const double* x);
 
 // If the array contains an invalid value, return the index for it,
 // otherwise return size.
-int FindInvalidValue(const int size, const double* x);
+CERES_EXPORT_INTERNAL int FindInvalidValue(const int size, const double* x);
 
 // Utility routine to print an array of doubles to a string. If the
 // array pointer is NULL, it is treated as an array of zeros.
-void AppendArrayToString(const int size, const double* x, std::string* result);
+CERES_EXPORT_INTERNAL void AppendArrayToString(const int size,
+                                               const double* x,
+                                               std::string* result);
 
 // This routine takes an array of integer values, sorts and uniques
 // them and then maps each value in the array to its position in the
@@ -79,7 +82,7 @@
 // gets mapped to
 //
 // [1 0 2 3 0 1 3]
-void MapValuesToContiguousRange(int size, int* array);
+CERES_EXPORT_INTERNAL void MapValuesToContiguousRange(int size, int* array);
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/array_utils_test.cc b/internal/ceres/array_utils_test.cc
index 77379d9..6c0ea84 100644
--- a/internal/ceres/array_utils_test.cc
+++ b/internal/ceres/array_utils_test.cc
@@ -30,9 +30,10 @@
 
 #include "ceres/array_utils.h"
 
-#include <limits>
 #include <cmath>
+#include <limits>
 #include <vector>
+
 #include "gtest/gtest.h"
 
 namespace ceres {
diff --git a/internal/ceres/autodiff_benchmarks/CMakeLists.txt b/internal/ceres/autodiff_benchmarks/CMakeLists.txt
new file mode 100644
index 0000000..610ebc3
--- /dev/null
+++ b/internal/ceres/autodiff_benchmarks/CMakeLists.txt
@@ -0,0 +1,17 @@
+# TODO: Add support for other compilers
+if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+  # Increase the inlining threshold only for those functions marked with an
+  # inline hint. This is typically far more realistic to significantly increase
+  # in a large code-base than -inline-threshold as that has a larger scope.
+  list(APPEND CERES_BENCHMARK_FLAGS "-mllvm" "-inlinehint-threshold=1000000")
+endif()
+
+add_executable(autodiff_benchmarks autodiff_benchmarks.cc)
+add_dependencies_to_benchmark(autodiff_benchmarks)
+target_compile_options(autodiff_benchmarks PRIVATE ${CERES_BENCHMARK_FLAGS})
+
+# All other flags + fast-math
+list(APPEND CERES_BENCHMARK_FAST_MATH_FLAGS ${CERES_BENCHMARK_FLAGS} "-ffast-math")
+add_executable(autodiff_benchmarks_fast_math autodiff_benchmarks.cc)
+add_dependencies_to_benchmark(autodiff_benchmarks_fast_math)
+target_compile_options(autodiff_benchmarks_fast_math PRIVATE ${CERES_BENCHMARK_FAST_MATH_FLAGS})
diff --git a/internal/ceres/autodiff_benchmarks/autodiff_benchmarks.cc b/internal/ceres/autodiff_benchmarks/autodiff_benchmarks.cc
new file mode 100644
index 0000000..87e0067
--- /dev/null
+++ b/internal/ceres/autodiff_benchmarks/autodiff_benchmarks.cc
@@ -0,0 +1,430 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2020 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// 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: darius.rueckert@fau.de (Darius Rueckert)
+
+#include <memory>
+#include <random>
+#include <utility>
+
+#include "benchmark/benchmark.h"
+#include "ceres/autodiff_benchmarks/brdf_cost_function.h"
+#include "ceres/autodiff_benchmarks/constant_cost_function.h"
+#include "ceres/autodiff_benchmarks/linear_cost_functions.h"
+#include "ceres/autodiff_benchmarks/photometric_error.h"
+#include "ceres/autodiff_benchmarks/relative_pose_error.h"
+#include "ceres/autodiff_benchmarks/snavely_reprojection_error.h"
+#include "ceres/ceres.h"
+
+namespace ceres {
+
+enum Dynamic { kNotDynamic, kDynamic };
+
+// Transforms a static functor into a dynamic one.
+template <typename CostFunctionType, int kNumParameterBlocks>
+class ToDynamic {
+ public:
+  template <typename... _Args>
+  explicit ToDynamic(_Args&&... __args)
+      : cost_function_(std::forward<_Args>(__args)...) {}
+
+  template <typename T>
+  bool operator()(const T* const* parameters, T* residuals) const {
+    return Apply(
+        parameters, residuals, std::make_index_sequence<kNumParameterBlocks>());
+  }
+
+ private:
+  template <typename T, size_t... Indices>
+  bool Apply(const T* const* parameters,
+             T* residuals,
+             std::index_sequence<Indices...>) const {
+    return cost_function_(parameters[Indices]..., residuals);
+  }
+
+  CostFunctionType cost_function_;
+};
+
+template <int kParameterBlockSize>
+static void BM_ConstantAnalytic(benchmark::State& state) {
+  constexpr int num_residuals = 1;
+  std::array<double, kParameterBlockSize> parameters_values;
+  std::iota(parameters_values.begin(), parameters_values.end(), 0);
+  double* parameters[] = {parameters_values.data()};
+
+  std::array<double, num_residuals> residuals;
+
+  std::array<double, num_residuals * kParameterBlockSize> jacobian_values;
+  double* jacobians[] = {jacobian_values.data()};
+
+  std::unique_ptr<ceres::CostFunction> cost_function(
+      new AnalyticConstantCostFunction<kParameterBlockSize>());
+
+  for (auto _ : state) {
+    cost_function->Evaluate(parameters, residuals.data(), jacobians);
+  }
+}
+
+// Helpers for CostFunctionFactory.
+template <typename DynamicCostFunctionType>
+void AddParameterBlocks(DynamicCostFunctionType*) {}
+
+template <int HeadN, int... TailNs, typename DynamicCostFunctionType>
+void AddParameterBlocks(DynamicCostFunctionType* dynamic_function) {
+  dynamic_function->AddParameterBlock(HeadN);
+  AddParameterBlocks<TailNs...>(dynamic_function);
+}
+
+// Creates an autodiff cost function wrapping `CostFunctor`, with
+// `kNumResiduals` residuals and parameter blocks with sized `Ns..`.
+// Depending on `kIsDynamic`, either a static or dynamic cost function is
+// created.
+// `args` are forwarded to the `CostFunctor` constructor.
+template <Dynamic kIsDynamic>
+struct CostFunctionFactory {};
+
+template <>
+struct CostFunctionFactory<kNotDynamic> {
+  template <typename CostFunctor,
+            int kNumResiduals,
+            int... Ns,
+            typename... Args>
+  static std::unique_ptr<ceres::CostFunction> Create(Args&&... args) {
+    return std::make_unique<
+        ceres::AutoDiffCostFunction<CostFunctor, kNumResiduals, Ns...>>(
+        new CostFunctor(std::forward<Args>(args)...));
+  }
+};
+
+template <>
+struct CostFunctionFactory<kDynamic> {
+  template <typename CostFunctor,
+            int kNumResiduals,
+            int... Ns,
+            typename... Args>
+  static std::unique_ptr<ceres::CostFunction> Create(Args&&... args) {
+    constexpr const int kNumParameterBlocks = sizeof...(Ns);
+    auto dynamic_function = std::make_unique<ceres::DynamicAutoDiffCostFunction<
+        ToDynamic<CostFunctor, kNumParameterBlocks>>>(
+        new ToDynamic<CostFunctor, kNumParameterBlocks>(
+            std::forward<Args>(args)...));
+    dynamic_function->SetNumResiduals(kNumResiduals);
+    AddParameterBlocks<Ns...>(dynamic_function.get());
+    return dynamic_function;
+  }
+};
+
+template <int kParameterBlockSize, Dynamic kIsDynamic>
+static void BM_ConstantAutodiff(benchmark::State& state) {
+  constexpr int num_residuals = 1;
+  std::array<double, kParameterBlockSize> parameters_values;
+  std::iota(parameters_values.begin(), parameters_values.end(), 0);
+  double* parameters[] = {parameters_values.data()};
+
+  std::array<double, num_residuals> residuals;
+
+  std::array<double, num_residuals * kParameterBlockSize> jacobian_values;
+  double* jacobians[] = {jacobian_values.data()};
+
+  std::unique_ptr<ceres::CostFunction> cost_function =
+      CostFunctionFactory<kIsDynamic>::
+          template Create<ConstantCostFunction<kParameterBlockSize>, 1, 1>();
+
+  for (auto _ : state) {
+    cost_function->Evaluate(parameters, residuals.data(), jacobians);
+  }
+}
+
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 1);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 1, kNotDynamic);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 1, kDynamic);
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 10);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 10, kNotDynamic);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 10, kDynamic);
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 20);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 20, kNotDynamic);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 20, kDynamic);
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 30);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 30, kNotDynamic);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 30, kDynamic);
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 40);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 40, kNotDynamic);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 40, kDynamic);
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 50);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 50, kNotDynamic);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 50, kDynamic);
+BENCHMARK_TEMPLATE(BM_ConstantAnalytic, 60);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 60, kNotDynamic);
+BENCHMARK_TEMPLATE(BM_ConstantAutodiff, 60, kDynamic);
+
+template <Dynamic kIsDynamic>
+static void BM_Linear1AutoDiff(benchmark::State& state) {
+  double parameter_block1[] = {1.};
+  double* parameters[] = {parameter_block1};
+
+  double jacobian1[1];
+  double residuals[1];
+  double* jacobians[] = {jacobian1};
+
+  std::unique_ptr<ceres::CostFunction> cost_function = CostFunctionFactory<
+      kIsDynamic>::template Create<Linear1CostFunction, 1, 1>();
+
+  for (auto _ : state) {
+    cost_function->Evaluate(
+        parameters, residuals, state.range(0) ? jacobians : nullptr);
+  }
+}
+BENCHMARK_TEMPLATE(BM_Linear1AutoDiff, kNotDynamic)->Arg(0)->Arg(1);
+BENCHMARK_TEMPLATE(BM_Linear1AutoDiff, kDynamic)->Arg(0)->Arg(1);
+
+template <Dynamic kIsDynamic>
+static void BM_Linear10AutoDiff(benchmark::State& state) {
+  double parameter_block1[] = {1., 2., 3., 4., 5., 6., 7., 8., 9., 10.};
+  double* parameters[] = {parameter_block1};
+
+  double jacobian1[10 * 10];
+  double residuals[10];
+  double* jacobians[] = {jacobian1};
+
+  std::unique_ptr<ceres::CostFunction> cost_function = CostFunctionFactory<
+      kIsDynamic>::template Create<Linear10CostFunction, 10, 10>();
+
+  for (auto _ : state) {
+    cost_function->Evaluate(
+        parameters, residuals, state.range(0) ? jacobians : nullptr);
+  }
+}
+BENCHMARK_TEMPLATE(BM_Linear10AutoDiff, kNotDynamic)->Arg(0)->Arg(1);
+BENCHMARK_TEMPLATE(BM_Linear10AutoDiff, kDynamic)->Arg(0)->Arg(1);
+
+// From the NIST problem collection.
+struct Rat43CostFunctor {
+  Rat43CostFunctor(const double x, const double y) : x_(x), y_(y) {}
+
+  template <typename T>
+  inline bool operator()(const T* parameters, T* residuals) const {
+    const T& b1 = parameters[0];
+    const T& b2 = parameters[1];
+    const T& b3 = parameters[2];
+    const T& b4 = parameters[3];
+    residuals[0] = b1 * pow(1.0 + exp(b2 - b3 * x_), -1.0 / b4) - y_;
+    return true;
+  }
+
+  static constexpr int kNumParameterBlocks = 1;
+
+ private:
+  const double x_;
+  const double y_;
+};
+
+template <Dynamic kIsDynamic>
+static void BM_Rat43AutoDiff(benchmark::State& state) {
+  double parameter_block1[] = {1., 2., 3., 4.};
+  double* parameters[] = {parameter_block1};
+
+  double jacobian1[] = {0.0, 0.0, 0.0, 0.0};
+  double residuals;
+  double* jacobians[] = {jacobian1};
+  const double x = 0.2;
+  const double y = 0.3;
+  std::unique_ptr<ceres::CostFunction> cost_function =
+      CostFunctionFactory<kIsDynamic>::template Create<Rat43CostFunctor, 1, 4>(
+          x, y);
+
+  for (auto _ : state) {
+    cost_function->Evaluate(
+        parameters, &residuals, state.range(0) ? jacobians : nullptr);
+  }
+}
+BENCHMARK_TEMPLATE(BM_Rat43AutoDiff, kNotDynamic)->Arg(0)->Arg(1);
+BENCHMARK_TEMPLATE(BM_Rat43AutoDiff, kDynamic)->Arg(0)->Arg(1);
+
+template <Dynamic kIsDynamic>
+static void BM_SnavelyReprojectionAutoDiff(benchmark::State& state) {
+  double parameter_block1[] = {1., 2., 3., 4., 5., 6., 7., 8., 9.};
+  double parameter_block2[] = {1., 2., 3.};
+  double* parameters[] = {parameter_block1, parameter_block2};
+
+  double jacobian1[2 * 9];
+  double jacobian2[2 * 3];
+  double residuals[2];
+  double* jacobians[] = {jacobian1, jacobian2};
+
+  const double x = 0.2;
+  const double y = 0.3;
+  std::unique_ptr<ceres::CostFunction> cost_function = CostFunctionFactory<
+      kIsDynamic>::template Create<SnavelyReprojectionError, 2, 9, 3>(x, y);
+
+  for (auto _ : state) {
+    cost_function->Evaluate(
+        parameters, residuals, state.range(0) ? jacobians : nullptr);
+  }
+}
+
+BENCHMARK_TEMPLATE(BM_SnavelyReprojectionAutoDiff, kNotDynamic)->Arg(0)->Arg(1);
+BENCHMARK_TEMPLATE(BM_SnavelyReprojectionAutoDiff, kDynamic)->Arg(0)->Arg(1);
+
+template <Dynamic kIsDynamic>
+static void BM_PhotometricAutoDiff(benchmark::State& state) {
+  constexpr int PATCH_SIZE = 8;
+
+  using FunctorType = PhotometricError<PATCH_SIZE>;
+  using ImageType = Eigen::Matrix<uint8_t, 128, 128, Eigen::RowMajor>;
+
+  // Prepare parameter / residual / jacobian blocks.
+  double parameter_block1[] = {1., 2., 3., 4., 5., 6., 7.};
+  double parameter_block2[] = {1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1};
+  double parameter_block3[] = {1.};
+  double* parameters[] = {parameter_block1, parameter_block2, parameter_block3};
+
+  Eigen::Map<Eigen::Quaterniond>(parameter_block1).normalize();
+  Eigen::Map<Eigen::Quaterniond>(parameter_block2).normalize();
+
+  double jacobian1[FunctorType::PATCH_SIZE * FunctorType::POSE_SIZE];
+  double jacobian2[FunctorType::PATCH_SIZE * FunctorType::POSE_SIZE];
+  double jacobian3[FunctorType::PATCH_SIZE * FunctorType::POINT_SIZE];
+  double residuals[FunctorType::PATCH_SIZE];
+  double* jacobians[] = {jacobian1, jacobian2, jacobian3};
+
+  // Prepare data (fixed seed for repeatability).
+  std::mt19937::result_type seed = 42;
+  std::mt19937 gen(seed);
+  std::uniform_real_distribution<double> uniform01(0.0, 1.0);
+  std::uniform_int_distribution<unsigned int> uniform0255(0, 255);
+
+  FunctorType::Patch<double> intensities_host =
+      FunctorType::Patch<double>::NullaryExpr(
+          [&]() { return uniform0255(gen); });
+
+  // Set bearing vector's z component to 1, i.e. pointing away from the camera,
+  // to ensure they are (likely) in the domain of the projection function (given
+  // a small rotation between host and target frame).
+  FunctorType::PatchVectors<double> bearings_host =
+      FunctorType::PatchVectors<double>::NullaryExpr(
+          [&]() { return uniform01(gen); });
+  bearings_host.row(2).array() = 1;
+  bearings_host.colwise().normalize();
+
+  ImageType image = ImageType::NullaryExpr(
+      [&]() { return static_cast<uint8_t>(uniform0255(gen)); });
+  FunctorType::Grid grid(image.data(), 0, image.rows(), 0, image.cols());
+  FunctorType::Interpolator image_target(grid);
+
+  FunctorType::Intrinsics intrinsics;
+  intrinsics << 128, 128, 1, -1, 0.5, 0.5;
+
+  std::unique_ptr<ceres::CostFunction> cost_function =
+      CostFunctionFactory<kIsDynamic>::template Create<FunctorType,
+                                                       FunctorType::PATCH_SIZE,
+                                                       FunctorType::POSE_SIZE,
+                                                       FunctorType::POSE_SIZE,
+                                                       FunctorType::POINT_SIZE>(
+          intensities_host, bearings_host, image_target, intrinsics);
+
+  for (auto _ : state) {
+    cost_function->Evaluate(
+        parameters, residuals, state.range(0) ? jacobians : nullptr);
+  }
+}
+
+BENCHMARK_TEMPLATE(BM_PhotometricAutoDiff, kNotDynamic)->Arg(0)->Arg(1);
+BENCHMARK_TEMPLATE(BM_PhotometricAutoDiff, kDynamic)->Arg(0)->Arg(1);
+
+template <Dynamic kIsDynamic>
+static void BM_RelativePoseAutoDiff(benchmark::State& state) {
+  using FunctorType = RelativePoseError;
+
+  double parameter_block1[] = {1., 2., 3., 4., 5., 6., 7.};
+  double parameter_block2[] = {1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1};
+  double* parameters[] = {parameter_block1, parameter_block2};
+
+  Eigen::Map<Eigen::Quaterniond>(parameter_block1).normalize();
+  Eigen::Map<Eigen::Quaterniond>(parameter_block2).normalize();
+
+  double jacobian1[6 * 7];
+  double jacobian2[6 * 7];
+  double residuals[6];
+  double* jacobians[] = {jacobian1, jacobian2};
+
+  Eigen::Quaterniond q_i_j = Eigen::Quaterniond(1, 2, 3, 4).normalized();
+  Eigen::Vector3d t_i_j(1, 2, 3);
+
+  std::unique_ptr<ceres::CostFunction> cost_function =
+      CostFunctionFactory<kIsDynamic>::template Create<FunctorType, 6, 7, 7>(
+          q_i_j, t_i_j);
+
+  for (auto _ : state) {
+    cost_function->Evaluate(
+        parameters, residuals, state.range(0) ? jacobians : nullptr);
+  }
+}
+
+BENCHMARK_TEMPLATE(BM_RelativePoseAutoDiff, kNotDynamic)->Arg(0)->Arg(1);
+BENCHMARK_TEMPLATE(BM_RelativePoseAutoDiff, kDynamic)->Arg(0)->Arg(1);
+
+template <Dynamic kIsDynamic>
+static void BM_BrdfAutoDiff(benchmark::State& state) {
+  using FunctorType = Brdf;
+
+  double material[] = {1., 2., 3., 4., 5., 6., 7., 8., 9., 10.};
+  auto c = Eigen::Vector3d(0.1, 0.2, 0.3);
+  auto n = Eigen::Vector3d(-0.1, 0.5, 0.2).normalized();
+  auto v = Eigen::Vector3d(0.5, -0.2, 0.9).normalized();
+  auto l = Eigen::Vector3d(-0.3, 0.4, -0.3).normalized();
+  auto x = Eigen::Vector3d(0.5, 0.7, -0.1).normalized();
+  auto y = Eigen::Vector3d(0.2, -0.2, -0.2).normalized();
+
+  double* parameters[7] = {
+      material, c.data(), n.data(), v.data(), l.data(), x.data(), y.data()};
+
+  double jacobian[(10 + 6 * 3) * 3];
+  double residuals[3];
+  // clang-format off
+  double* jacobians[7] = {
+      jacobian + 0,      jacobian + 10 * 3, jacobian + 13 * 3,
+      jacobian + 16 * 3, jacobian + 19 * 3, jacobian + 22 * 3,
+      jacobian + 25 * 3,
+  };
+  // clang-format on
+
+  std::unique_ptr<ceres::CostFunction> cost_function = CostFunctionFactory<
+      kIsDynamic>::template Create<FunctorType, 3, 10, 3, 3, 3, 3, 3, 3>();
+
+  for (auto _ : state) {
+    cost_function->Evaluate(
+        parameters, residuals, state.range(0) ? jacobians : nullptr);
+  }
+}
+
+BENCHMARK_TEMPLATE(BM_BrdfAutoDiff, kNotDynamic)->Arg(0)->Arg(1);
+BENCHMARK_TEMPLATE(BM_BrdfAutoDiff, kDynamic)->Arg(0)->Arg(1);
+
+}  // namespace ceres
+
+BENCHMARK_MAIN();
diff --git a/internal/ceres/autodiff_benchmarks/brdf_cost_function.h b/internal/ceres/autodiff_benchmarks/brdf_cost_function.h
new file mode 100644
index 0000000..9d7c0cc
--- /dev/null
+++ b/internal/ceres/autodiff_benchmarks/brdf_cost_function.h
@@ -0,0 +1,223 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2020 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// 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: darius.rueckert@fau.de (Darius Rueckert)
+//
+//
+#ifndef CERES_INTERNAL_AUTODIFF_BENCHMARK_BRDF_COST_FUNCTION_H_
+#define CERES_INTERNAL_AUTODIFF_BENCHMARK_BRDF_COST_FUNCTION_H_
+
+#include <Eigen/Core>
+#include <cmath>
+
+namespace ceres {
+
+// The brdf is based on:
+// Burley, Brent, and Walt Disney Animation Studios. "Physically-based shading
+// at disney." ACM SIGGRAPH. Vol. 2012. 2012.
+//
+// The implementation is based on:
+// https://github.com/wdas/brdf/blob/master/src/brdfs/disney.brdf
+struct Brdf {
+ public:
+  Brdf() {}
+
+  template <typename T>
+  inline bool operator()(const T* const material,
+                         const T* const c_ptr,
+                         const T* const n_ptr,
+                         const T* const v_ptr,
+                         const T* const l_ptr,
+                         const T* const x_ptr,
+                         const T* const y_ptr,
+                         T* residual) const {
+    using Vec3 = Eigen::Matrix<T, 3, 1>;
+
+    T metallic = material[0];
+    T subsurface = material[1];
+    T specular = material[2];
+    T roughness = material[3];
+    T specular_tint = material[4];
+    T anisotropic = material[5];
+    T sheen = material[6];
+    T sheen_tint = material[7];
+    T clearcoat = material[8];
+    T clearcoat_gloss = material[9];
+
+    Eigen::Map<const Vec3> c(c_ptr);
+    Eigen::Map<const Vec3> n(n_ptr);
+    Eigen::Map<const Vec3> v(v_ptr);
+    Eigen::Map<const Vec3> l(l_ptr);
+    Eigen::Map<const Vec3> x(x_ptr);
+    Eigen::Map<const Vec3> y(y_ptr);
+
+    const T n_dot_l = n.dot(l);
+    const T n_dot_v = n.dot(v);
+
+    const Vec3 l_p_v = l + v;
+    const Vec3 h = l_p_v / l_p_v.norm();
+
+    const T n_dot_h = n.dot(h);
+    const T l_dot_h = l.dot(h);
+
+    const T h_dot_x = h.dot(x);
+    const T h_dot_y = h.dot(y);
+
+    const T c_dlum = T(0.3) * c[0] + T(0.6) * c[1] + T(0.1) * c[2];
+
+    const Vec3 c_tint = c / c_dlum;
+
+    const Vec3 c_spec0 =
+        Lerp(specular * T(0.08) *
+                 Lerp(Vec3(T(1), T(1), T(1)), c_tint, specular_tint),
+             c,
+             metallic);
+    const Vec3 c_sheen = Lerp(Vec3(T(1), T(1), T(1)), c_tint, sheen_tint);
+
+    // Diffuse fresnel - go from 1 at normal incidence to .5 at grazing
+    // and mix in diffuse retro-reflection based on roughness
+    const T fl = SchlickFresnel(n_dot_l);
+    const T fv = SchlickFresnel(n_dot_v);
+    const T fd_90 = T(0.5) + T(2) * l_dot_h * l_dot_h * roughness;
+    const T fd = Lerp(T(1), fd_90, fl) * Lerp(T(1), fd_90, fv);
+
+    // Based on Hanrahan-Krueger brdf approximation of isotropic bssrdf
+    // 1.25 scale is used to (roughly) preserve albedo
+    // Fss90 used to "flatten" retroreflection based on roughness
+    const T fss_90 = l_dot_h * l_dot_h * roughness;
+    const T fss = Lerp(T(1), fss_90, fl) * Lerp(T(1), fss_90, fv);
+    const T ss =
+        T(1.25) * (fss * (T(1) / (n_dot_l + n_dot_v) - T(0.5)) + T(0.5));
+
+    // specular
+    const T eps = T(0.001);
+    const T aspct = Aspect(anisotropic);
+    const T ax_temp = Square(roughness) / aspct;
+    const T ay_temp = Square(roughness) * aspct;
+    const T ax = (ax_temp < eps ? eps : ax_temp);
+    const T ay = (ay_temp < eps ? eps : ay_temp);
+    const T ds = GTR2Aniso(n_dot_h, h_dot_x, h_dot_y, ax, ay);
+    const T fh = SchlickFresnel(l_dot_h);
+    const Vec3 fs = Lerp(c_spec0, Vec3(T(1), T(1), T(1)), fh);
+    const T roughg = Square(roughness * T(0.5) + T(0.5));
+    const T ggxn_dot_l = SmithG_GGX(n_dot_l, roughg);
+    const T ggxn_dot_v = SmithG_GGX(n_dot_v, roughg);
+    const T gs = ggxn_dot_l * ggxn_dot_v;
+
+    // sheen
+    const Vec3 f_sheen = fh * sheen * c_sheen;
+
+    // clearcoat (ior = 1.5 -> F0 = 0.04)
+    const T a = Lerp(T(0.1), T(0.001), clearcoat_gloss);
+    const T dr = GTR1(n_dot_h, a);
+    const T fr = Lerp(T(0.04), T(1), fh);
+    const T cggxn_dot_l = SmithG_GGX(n_dot_l, T(0.25));
+    const T cggxn_dot_v = SmithG_GGX(n_dot_v, T(0.25));
+    const T gr = cggxn_dot_l * cggxn_dot_v;
+
+    const Vec3 result_no_cosine =
+        (T(1.0 / M_PI) * Lerp(fd, ss, subsurface) * c + f_sheen) *
+            (T(1) - metallic) +
+        gs * fs * ds +
+        Vec3(T(0.25), T(0.25), T(0.25)) * clearcoat * gr * fr * dr;
+    const Vec3 result = n_dot_l * result_no_cosine;
+    residual[0] = result(0);
+    residual[1] = result(1);
+    residual[2] = result(2);
+
+    return true;
+  }
+
+  template <typename T>
+  inline T SchlickFresnel(const T& u) const {
+    T m = T(1) - u;
+    const T m2 = m * m;
+    return m2 * m2 * m;  // (1-u)^5
+  }
+
+  template <typename T>
+  inline T Aspect(const T& anisotropic) const {
+    return T(sqrt(T(1) - anisotropic * T(0.9)));
+  }
+
+  template <typename T>
+  inline T SmithG_GGX(const T& n_dot_v, const T& alpha_g) const {
+    const T a = alpha_g * alpha_g;
+    const T b = n_dot_v * n_dot_v;
+    return T(1) / (n_dot_v + T(sqrt(a + b - a * b)));
+  }
+
+  // Generalized-Trowbridge-Reitz (GTR) Microfacet Distribution
+  // See paper, Appendix B
+  template <typename T>
+  inline T GTR1(const T& n_dot_h, const T& a) const {
+    T result = T(0);
+
+    if (a >= T(1)) {
+      result = T(1 / M_PI);
+    } else {
+      const T a2 = a * a;
+      const T t = T(1) + (a2 - T(1)) * n_dot_h * n_dot_h;
+      result = (a2 - T(1)) / (T(M_PI) * T(log(a2) * t));
+    }
+    return result;
+  }
+
+  template <typename T>
+  inline T GTR2Aniso(const T& n_dot_h,
+                     const T& h_dot_x,
+                     const T& h_dot_y,
+                     const T& ax,
+                     const T& ay) const {
+    return T(1) / (T(M_PI) * ax * ay *
+                   Square(Square(h_dot_x / ax) + Square(h_dot_y / ay) +
+                          n_dot_h * n_dot_h));
+  }
+
+  template <typename T>
+  inline T Lerp(const T& a, const T& b, const T& u) const {
+    return a + u * (b - a);
+  }
+
+  template <typename Derived1, typename Derived2>
+  inline typename Derived1::PlainObject Lerp(
+      const Eigen::MatrixBase<Derived1>& a,
+      const Eigen::MatrixBase<Derived2>& b,
+      typename Derived1::Scalar alpha) const {
+    return (typename Derived1::Scalar(1) - alpha) * a + alpha * b;
+  }
+
+  template <typename T>
+  inline T Square(const T& x) const {
+    return x * x;
+  }
+};
+
+}  // namespace ceres
+
+#endif  // CERES_INTERNAL_AUTODIFF_BENCHMARK_BRDF_COST_FUNCTION_H_
diff --git a/internal/ceres/autodiff_benchmarks/constant_cost_function.h b/internal/ceres/autodiff_benchmarks/constant_cost_function.h
new file mode 100644
index 0000000..2bbe4cb
--- /dev/null
+++ b/internal/ceres/autodiff_benchmarks/constant_cost_function.h
@@ -0,0 +1,66 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2020 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// 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: darius.rueckert@fau.de (Darius Rueckert)
+//
+//
+#ifndef CERES_INTERNAL_AUTODIFF_BENCHMARKS_CONSTANT_COST_FUNCTIONS_H_
+#define CERES_INTERNAL_AUTODIFF_BENCHMARKS_CONSTANT_COST_FUNCTIONS_H_
+
+#include "ceres/sized_cost_function.h"
+
+namespace ceres {
+
+template <int kParameterBlockSize>
+struct ConstantCostFunction {
+  template <typename T>
+  inline bool operator()(const T* const x, T* residuals) const {
+    residuals[0] = T(5);
+    return true;
+  }
+};
+
+template <int kParameterBlockSize>
+struct AnalyticConstantCostFunction
+    : public ceres::SizedCostFunction<1, kParameterBlockSize> {
+  virtual bool Evaluate(double const* const* parameters,
+                        double* residuals,
+                        double** jacobians) const {
+    residuals[0] = 5.0;
+    if (jacobians) {
+      if (jacobians[0]) {
+        memset(jacobians[0], 0, sizeof(double) * kParameterBlockSize);
+      }
+    }
+    return true;
+  }
+};
+
+}  // namespace ceres
+
+#endif  // CERES_INTERNAL_AUTODIFF_BENCHMARKS_CONSTANT_COST_FUNCTIONS_H_
diff --git a/internal/ceres/autodiff_benchmarks/linear_cost_functions.h b/internal/ceres/autodiff_benchmarks/linear_cost_functions.h
new file mode 100644
index 0000000..2f2552f
--- /dev/null
+++ b/internal/ceres/autodiff_benchmarks/linear_cost_functions.h
@@ -0,0 +1,58 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2020 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// 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: darius.rueckert@fau.de (Darius Rueckert)
+//
+//
+#ifndef CERES_INTERNAL_AUTODIFF_BENCHMARKS_LINEAR_COST_FUNCTIONS_H_
+#define CERES_INTERNAL_AUTODIFF_BENCHMARKS_LINEAR_COST_FUNCTIONS_H_
+
+#include "ceres/rotation.h"
+
+namespace ceres {
+
+struct Linear1CostFunction {
+  template <typename T>
+  inline bool operator()(const T* const x, T* residuals) const {
+    residuals[0] = x[0] + T(10);
+    return true;
+  }
+};
+
+struct Linear10CostFunction {
+  template <typename T>
+  inline bool operator()(const T* const x, T* residuals) const {
+    for (int i = 0; i < 10; ++i) {
+      residuals[i] = x[i] + T(i);
+    }
+    return true;
+  }
+};
+}  // namespace ceres
+
+#endif  // CERES_INTERNAL_AUTODIFF_BENCHMARKS_LINEAR_COST_FUNCTIONS_H_
diff --git a/internal/ceres/autodiff_benchmarks/photometric_error.h b/internal/ceres/autodiff_benchmarks/photometric_error.h
new file mode 100644
index 0000000..8ed278d
--- /dev/null
+++ b/internal/ceres/autodiff_benchmarks/photometric_error.h
@@ -0,0 +1,191 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2020 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// 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: nikolaus@nikolaus-demmel.de (Nikolaus Demmel)
+//
+//
+#ifndef CERES_INTERNAL_AUTODIFF_BENCHMARK_PHOTOMETRIC_ERROR_H_
+#define CERES_INTERNAL_AUTODIFF_BENCHMARK_PHOTOMETRIC_ERROR_H_
+
+#include <Eigen/Dense>
+
+#include "ceres/cubic_interpolation.h"
+
+namespace ceres {
+
+// Photometric residual that computes the intensity difference for a patch
+// between host and target frame. The point is parameterized with inverse
+// distance relative to the host frame. The relative pose between host and
+// target frame is computed from their respective absolute poses.
+//
+// The residual is similar to the one defined by Engel et al. [1]. Differences
+// include:
+//
+// 1. Use of a camera model based on spherical projection, namely the enhanced
+// unified camera model [2][3]. This is intended to bring some variability to
+// the benchmark compared to the SnavelyReprojection that uses a
+// polynomial-based distortion model.
+//
+// 2. To match the camera model, inverse distance parameterization is used for
+// points instead of inverse depth [4].
+//
+// 3. For simplicity, camera intrinsics are assumed constant, and thus host
+// frame points are passed as (unprojected) bearing vectors, which avoids the
+// need for an 'unproject' function.
+//
+// 4. Some details of the residual in [1] are omitted for simplicity: The
+// brightness transform parameters [a,b], the constant pre-weight w, and the
+// per-pixel robust norm.
+//
+// [1] J. Engel, V. Koltun and D. Cremers, "Direct Sparse Odometry," in IEEE
+// Transactions on Pattern Analysis and Machine Intelligence, vol. 40, no. 3,
+// pp. 611-625, 1 March 2018.
+//
+// [2] B. Khomutenko, G. Garcia and P. Martinet, "An Enhanced Unified Camera
+// Model," in IEEE Robotics and Automation Letters, vol. 1, no. 1, pp. 137-144,
+// Jan. 2016.
+//
+// [3] V. Usenko, N. Demmel and D. Cremers, "The Double Sphere Camera Model,"
+// 2018 International Conference on 3D Vision (3DV), Verona, 2018, pp. 552-560.
+//
+// [4] H. Matsuki, L. von Stumberg, V. Usenko, J. Stückler and D. Cremers,
+// "Omnidirectional DSO: Direct Sparse Odometry With Fisheye Cameras," in IEEE
+// Robotics and Automation Letters, vol. 3, no. 4, pp. 3693-3700, Oct. 2018.
+template <int PATCH_SIZE_ = 8>
+struct PhotometricError {
+  static constexpr int PATCH_SIZE = PATCH_SIZE_;
+  static constexpr int POSE_SIZE = 7;
+  static constexpr int POINT_SIZE = 1;
+
+  using Grid = Grid2D<uint8_t, 1>;
+  using Interpolator = BiCubicInterpolator<Grid>;
+  using Intrinsics = Eigen::Array<double, 6, 1>;
+
+  template <typename T>
+  using Patch = Eigen::Array<T, PATCH_SIZE, 1>;
+
+  template <typename T>
+  using PatchVectors = Eigen::Matrix<T, 3, PATCH_SIZE>;
+
+  PhotometricError(const Patch<double>& intensities_host,
+                   const PatchVectors<double>& bearings_host,
+                   const Interpolator& image_target,
+                   const Intrinsics& intrinsics)
+      : intensities_host_(intensities_host),
+        bearings_host_(bearings_host),
+        image_target_(image_target),
+        intrinsics_(intrinsics) {}
+
+  template <typename T>
+  inline bool Project(Eigen::Matrix<T, 2, 1>& proj,
+                      const Eigen::Matrix<T, 3, 1>& p) const {
+    const double& fx = intrinsics_[0];
+    const double& fy = intrinsics_[1];
+    const double& cx = intrinsics_[2];
+    const double& cy = intrinsics_[3];
+    const double& alpha = intrinsics_[4];
+    const double& beta = intrinsics_[5];
+
+    const T rho2 = beta * (p.x() * p.x() + p.y() * p.y()) + p.z() * p.z();
+    const T rho = sqrt(rho2);
+
+    // Check if 3D point is in domain of projection function.
+    // See (8) and (17) in [3].
+    constexpr double NUMERIC_EPSILON = 1e-10;
+    const double w =
+        alpha > 0.5 ? (1.0 - alpha) / alpha : alpha / (1.0 - alpha);
+    if (p.z() <= -w * rho + NUMERIC_EPSILON) {
+      return false;
+    }
+
+    const T norm = alpha * rho + (1.0 - alpha) * p.z();
+    const T norm_inv = 1.0 / norm;
+
+    const T mx = p.x() * norm_inv;
+    const T my = p.y() * norm_inv;
+
+    proj[0] = fx * mx + cx;
+    proj[1] = fy * my + cy;
+
+    return true;
+  }
+
+  template <typename T>
+  inline bool operator()(const T* const pose_host_ptr,
+                         const T* const pose_target_ptr,
+                         const T* const idist_ptr,
+                         T* residuals_ptr) const {
+    Eigen::Map<const Eigen::Quaternion<T>> q_w_h(pose_host_ptr);
+    Eigen::Map<const Eigen::Matrix<T, 3, 1>> t_w_h(pose_host_ptr + 4);
+    Eigen::Map<const Eigen::Quaternion<T>> q_w_t(pose_target_ptr);
+    Eigen::Map<const Eigen::Matrix<T, 3, 1>> t_w_t(pose_target_ptr + 4);
+    const T& idist = *idist_ptr;
+    Eigen::Map<Patch<T>> residuals(residuals_ptr);
+
+    // Compute relative pose from host to target frame.
+    const Eigen::Quaternion<T> q_t_h = q_w_t.conjugate() * q_w_h;
+    const Eigen::Matrix<T, 3, 3> R_t_h = q_t_h.toRotationMatrix();
+    const Eigen::Matrix<T, 3, 1> t_t_h = q_w_t.conjugate() * (t_w_h - t_w_t);
+
+    // Transform points from host to target frame. 3D point in target frame is
+    // scaled by idist for numerical stability when idist is close to 0
+    // (projection is invariant to scaling).
+    PatchVectors<T> p_target_scaled =
+        (R_t_h * bearings_host_).colwise() + idist * t_t_h;
+
+    // Project points and interpolate image.
+    Patch<T> intensities_target;
+    for (int i = 0; i < p_target_scaled.cols(); ++i) {
+      Eigen::Matrix<T, 2, 1> uv;
+      if (!Project(uv, Eigen::Matrix<T, 3, 1>(p_target_scaled.col(i)))) {
+        // If any point of the patch is outside the domain of the projection
+        // function, the residual cannot be evaluated. For the benchmark we want
+        // to avoid this case and thus throw an exception to indicate
+        // immediately if it does actually happen after possible future changes.
+        throw std::runtime_error("Benchmark data leads to invalid projection.");
+      }
+
+      // Mind the order of u and v: Evaluate takes (row, column), but u is
+      // left-to-right and v top-to-bottom image axis.
+      image_target_.Evaluate(uv[1], uv[0], &intensities_target[i]);
+    }
+
+    // Residual is intensity difference between host and target frame.
+    residuals = intensities_target - intensities_host_;
+
+    return true;
+  }
+
+ private:
+  const Patch<double>& intensities_host_;
+  const PatchVectors<double>& bearings_host_;
+  const Interpolator& image_target_;
+  const Intrinsics& intrinsics_;
+};
+}  // namespace ceres
+#endif  // CERES_INTERNAL_AUTODIFF_BENCHMARK_PHOTOMETRIC_ERROR_H_
diff --git a/internal/ceres/autodiff_benchmarks/relative_pose_error.h b/internal/ceres/autodiff_benchmarks/relative_pose_error.h
new file mode 100644
index 0000000..b5c1a93
--- /dev/null
+++ b/internal/ceres/autodiff_benchmarks/relative_pose_error.h
@@ -0,0 +1,87 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2020 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// 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: nikolaus@nikolaus-demmel.de (Nikolaus Demmel)
+//
+//
+#ifndef CERES_INTERNAL_AUTODIFF_BENCHMARK_RELATIVE_POSE_ERROR_H_
+#define CERES_INTERNAL_AUTODIFF_BENCHMARK_RELATIVE_POSE_ERROR_H_
+
+#include <Eigen/Dense>
+
+#include "ceres/rotation.h"
+
+namespace ceres {
+
+// Relative pose error as one might use in SE(3) pose graph optimization.
+// The measurement is a relative pose T_i_j, and the parameters are absolute
+// poses T_w_i and T_w_j. For the residual we use the log of the the residual
+// pose, in split representation SO(3) x R^3.
+struct RelativePoseError {
+  RelativePoseError(const Eigen::Quaterniond& q_i_j,
+                    const Eigen::Vector3d& t_i_j)
+      : meas_q_i_j_(q_i_j), meas_t_i_j_(t_i_j) {}
+
+  template <typename T>
+  inline bool operator()(const T* const pose_i_ptr,
+                         const T* const pose_j_ptr,
+                         T* residuals_ptr) const {
+    Eigen::Map<const Eigen::Quaternion<T>> q_w_i(pose_i_ptr);
+    Eigen::Map<const Eigen::Matrix<T, 3, 1>> t_w_i(pose_i_ptr + 4);
+    Eigen::Map<const Eigen::Quaternion<T>> q_w_j(pose_j_ptr);
+    Eigen::Map<const Eigen::Matrix<T, 3, 1>> t_w_j(pose_j_ptr + 4);
+    Eigen::Map<Eigen::Matrix<T, 6, 1>> residuals(residuals_ptr);
+
+    // Compute estimate of relative pose from i to j.
+    const Eigen::Quaternion<T> est_q_j_i = q_w_j.conjugate() * q_w_i;
+    const Eigen::Matrix<T, 3, 1> est_t_j_i =
+        q_w_j.conjugate() * (t_w_i - t_w_j);
+
+    // Compute residual pose.
+    const Eigen::Quaternion<T> res_q = meas_q_i_j_.cast<T>() * est_q_j_i;
+    const Eigen::Matrix<T, 3, 1> res_t =
+        meas_q_i_j_.cast<T>() * est_t_j_i + meas_t_i_j_;
+
+    // Convert quaternion to ceres convention (Eigen stores xyzw, Ceres wxyz).
+    Eigen::Matrix<T, 4, 1> res_q_ceres;
+    res_q_ceres << res_q.w(), res_q.vec();
+
+    // Residual is log of pose. Use split representation SO(3) x R^3.
+    QuaternionToAngleAxis(res_q_ceres.data(), residuals.data());
+    residuals.template bottomRows<3>() = res_t;
+
+    return true;
+  }
+
+ private:
+  // Measurement of relative pose from j to i.
+  Eigen::Quaterniond meas_q_i_j_;
+  Eigen::Vector3d meas_t_i_j_;
+};
+}  // namespace ceres
+#endif  // CERES_INTERNAL_AUTODIFF_BENCHMARK_RELATIVE_POSE_ERROR_H_
diff --git a/internal/ceres/autodiff_benchmarks/snavely_reprojection_error.h b/internal/ceres/autodiff_benchmarks/snavely_reprojection_error.h
new file mode 100644
index 0000000..795342f
--- /dev/null
+++ b/internal/ceres/autodiff_benchmarks/snavely_reprojection_error.h
@@ -0,0 +1,87 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2020 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// 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: darius.rueckert@fau.de (Darius Rueckert)
+//
+//
+#ifndef CERES_INTERNAL_AUTODIFF_BENCHMARK_SNAVELY_REPROJECTION_ERROR_H_
+#define CERES_INTERNAL_AUTODIFF_BENCHMARK_SNAVELY_REPROJECTION_ERROR_H_
+
+#include "ceres/rotation.h"
+
+namespace ceres {
+
+struct SnavelyReprojectionError {
+  SnavelyReprojectionError(double observed_x, double observed_y)
+      : observed_x(observed_x), observed_y(observed_y) {}
+
+  SnavelyReprojectionError() = default;
+  template <typename T>
+  inline bool operator()(const T* const camera,
+                         const T* const point,
+                         T* residuals) const {
+    T ox = T(observed_x);
+    T oy = T(observed_y);
+
+    // camera[0,1,2] are the angle-axis rotation.
+    T p[3];
+    ceres::AngleAxisRotatePoint(camera, point, p);
+
+    // camera[3,4,5] are the translation.
+    p[0] += camera[3];
+    p[1] += camera[4];
+    p[2] += camera[5];
+
+    // Compute the center of distortion. The sign change comes from
+    // the camera model that Noah Snavely's Bundler assumes, whereby
+    // the camera coordinate system has a negative z axis.
+    const T xp = -p[0] / p[2];
+    const T yp = -p[1] / p[2];
+
+    // Apply second and fourth order radial distortion.
+    const T& l1 = camera[7];
+    const T& l2 = camera[8];
+    const T r2 = xp * xp + yp * yp;
+    const T distortion = T(1.0) + r2 * (l1 + l2 * r2);
+
+    // Compute final projected point position.
+    const T& focal = camera[6];
+    const T predicted_x = focal * distortion * xp;
+    const T predicted_y = focal * distortion * yp;
+
+    // The error is the difference between the predicted and observed position.
+    residuals[0] = predicted_x - ox;
+    residuals[1] = predicted_y - oy;
+
+    return true;
+  }
+  double observed_x;
+  double observed_y;
+};
+}  // namespace ceres
+#endif  // CERES_INTERNAL_AUTODIFF_BENCHMARK_SNAVELY_REPROJECTION_ERROR_H_
diff --git a/internal/ceres/autodiff_cost_function_benchmark.cc b/internal/ceres/autodiff_cost_function_benchmark.cc
deleted file mode 100644
index b9c106e..0000000
--- a/internal/ceres/autodiff_cost_function_benchmark.cc
+++ /dev/null
@@ -1,116 +0,0 @@
-// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2018 Google Inc. All rights reserved.
-// http://ceres-solver.org/
-//
-// 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.
-//
-// Authors: sameeragarwal@google.com (Sameer Agarwal)
-
-#include <memory>
-
-#include "benchmark/benchmark.h"
-#include "ceres/ceres.h"
-#include "ceres/jet.h"
-
-namespace ceres {
-
-// From the NIST problem collection.
-struct Rat43CostFunctor {
-  Rat43CostFunctor(const double x, const double y) : x_(x), y_(y) {}
-
-  template <typename T>
-  bool operator()(const T* parameters, T* residuals) const {
-    const T& b1 = parameters[0];
-    const T& b2 = parameters[1];
-    const T& b3 = parameters[2];
-    const T& b4 = parameters[3];
-    residuals[0] = b1 * pow(1.0 + exp(b2 - b3 * x_), -1.0 / b4) - y_;
-    return true;
-  }
-
- private:
-  const double x_;
-  const double y_;
-};
-
-// Simple implementation of autodiff using Jets directly instead of
-// going through the machinery of AutoDiffCostFunction, which does
-// the same thing, but much more generically.
-class Rat43Automatic : public ceres::SizedCostFunction<1, 4> {
- public:
-  Rat43Automatic(const Rat43CostFunctor* functor) : functor_(functor) {}
-  virtual ~Rat43Automatic() {}
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
-    if (!jacobians) {
-      return (*functor_)(parameters[0], residuals);
-    }
-
-    typedef ceres::Jet<double, 4> JetT;
-    JetT jets[4];
-    for (int i = 0; i < 4; ++i) {
-      jets[i].a = parameters[0][i];
-      jets[i].v.setZero();
-      jets[i].v[i] = 1.0;
-    }
-
-    JetT result;
-    (*functor_)(jets, &result);
-
-    residuals[0] = result.a;
-    for (int i = 0; i < 4; ++i) {
-      jacobians[0][i] = result.v[i];
-    }
-    return true;
-  }
-
- private:
-  std::unique_ptr<const Rat43CostFunctor> functor_;
-};
-
-static void BM_Rat43AutoDiff(benchmark::State& state) {
-  double parameter_block1[] = {1., 2., 3., 4.};
-  double* parameters[] = {parameter_block1};
-
-  double jacobian1[] = {0.0, 0.0, 0.0, 0.0};
-  double residuals;
-  double* jacobians[] = {jacobian1};
-  const double x = 0.2;
-  const double y = 0.3;
-  std::unique_ptr<ceres::CostFunction> cost_function(
-      new ceres::AutoDiffCostFunction<Rat43CostFunctor, 1, 4>(
-          new Rat43CostFunctor(x, y)));
-
-  while (state.KeepRunning()) {
-    cost_function->Evaluate(
-        parameters, &residuals, state.range(0) ? jacobians : nullptr);
-  }
-}
-BENCHMARK(BM_Rat43AutoDiff)->Arg(0)->Arg(1);
-
-}  // namespace ceres
-
-BENCHMARK_MAIN();
diff --git a/internal/ceres/autodiff_cost_function_test.cc b/internal/ceres/autodiff_cost_function_test.cc
index 4795579..cc340f6 100644
--- a/internal/ceres/autodiff_cost_function_test.cc
+++ b/internal/ceres/autodiff_cost_function_test.cc
@@ -1,5 +1,5 @@
 // Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2015 Google Inc. All rights reserved.
+// Copyright 2019 Google Inc. All rights reserved.
 // http://ceres-solver.org/
 //
 // Redistribution and use in source and binary forms, with or without
@@ -30,33 +30,32 @@
 
 #include "ceres/autodiff_cost_function.h"
 
-#include <cstddef>
 #include <memory>
 
-#include "gtest/gtest.h"
-#include "ceres/cost_function.h"
 #include "ceres/array_utils.h"
+#include "ceres/cost_function.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
 
 class BinaryScalarCost {
  public:
-  explicit BinaryScalarCost(double a): a_(a) {}
+  explicit BinaryScalarCost(double a) : a_(a) {}
   template <typename T>
-  bool operator()(const T* const x, const T* const y,
-                  T* cost) const {
-    cost[0] = x[0] * y[0] + x[1] * y[1]  - T(a_);
+  bool operator()(const T* const x, const T* const y, T* cost) const {
+    cost[0] = x[0] * y[0] + x[1] * y[1] - T(a_);
     return true;
   }
+
  private:
   double a_;
 };
 
 TEST(AutodiffCostFunction, BilinearDifferentiationTest) {
-  CostFunction* cost_function  =
-    new AutoDiffCostFunction<BinaryScalarCost, 1, 2, 2>(
-        new BinaryScalarCost(1.0));
+  CostFunction* cost_function =
+      new AutoDiffCostFunction<BinaryScalarCost, 1, 2, 2>(
+          new BinaryScalarCost(1.0));
 
   double** parameters = new double*[2];
   parameters[0] = new double[2];
@@ -74,7 +73,7 @@
 
   double residuals = 0.0;
 
-  cost_function->Evaluate(parameters, &residuals, NULL);
+  cost_function->Evaluate(parameters, &residuals, nullptr);
   EXPECT_EQ(10.0, residuals);
 
   cost_function->Evaluate(parameters, &residuals, jacobians);
@@ -113,10 +112,19 @@
 };
 
 TEST(AutodiffCostFunction, ManyParameterAutodiffInstantiates) {
-  CostFunction* cost_function  =
-      new AutoDiffCostFunction<
-          TenParameterCost, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>(
-              new TenParameterCost);
+  CostFunction* cost_function =
+      new AutoDiffCostFunction<TenParameterCost,
+                               1,
+                               1,
+                               1,
+                               1,
+                               1,
+                               1,
+                               1,
+                               1,
+                               1,
+                               1,
+                               1>(new TenParameterCost);
 
   double** parameters = new double*[10];
   double** jacobians = new double*[10];
@@ -128,7 +136,7 @@
 
   double residuals = 0.0;
 
-  cost_function->Evaluate(parameters, &residuals, NULL);
+  cost_function->Evaluate(parameters, &residuals, nullptr);
   EXPECT_EQ(45.0, residuals);
 
   cost_function->Evaluate(parameters, &residuals, jacobians);
diff --git a/internal/ceres/autodiff_first_order_function_test.cc b/internal/ceres/autodiff_first_order_function_test.cc
new file mode 100644
index 0000000..7db7835
--- /dev/null
+++ b/internal/ceres/autodiff_first_order_function_test.cc
@@ -0,0 +1,77 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2019 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+
+#include "ceres/autodiff_first_order_function.h"
+
+#include <memory>
+
+#include "ceres/array_utils.h"
+#include "ceres/first_order_function.h"
+#include "gtest/gtest.h"
+
+namespace ceres {
+namespace internal {
+
+class QuadraticCostFunctor {
+ public:
+  explicit QuadraticCostFunctor(double a) : a_(a) {}
+  template <typename T>
+  bool operator()(const T* const x, T* cost) const {
+    cost[0] = x[0] * x[1] + x[2] * x[3] - T(a_);
+    return true;
+  }
+
+ private:
+  double a_;
+};
+
+TEST(AutoDiffFirstOrderFunction, BilinearDifferentiationTest) {
+  std::unique_ptr<FirstOrderFunction> function(
+      new AutoDiffFirstOrderFunction<QuadraticCostFunctor, 4>(
+          new QuadraticCostFunctor(1.0)));
+
+  double parameters[4] = {1.0, 2.0, 3.0, 4.0};
+  double gradient[4];
+  double cost;
+
+  function->Evaluate(parameters, &cost, nullptr);
+  EXPECT_EQ(cost, 13.0);
+
+  cost = -1.0;
+  function->Evaluate(parameters, &cost, gradient);
+  EXPECT_EQ(cost, 13.0);
+  EXPECT_EQ(gradient[0], parameters[1]);
+  EXPECT_EQ(gradient[1], parameters[0]);
+  EXPECT_EQ(gradient[2], parameters[3]);
+  EXPECT_EQ(gradient[3], parameters[2]);
+}
+
+}  // namespace internal
+}  // namespace ceres
diff --git a/internal/ceres/autodiff_local_parameterization_test.cc b/internal/ceres/autodiff_local_parameterization_test.cc
index f2396dc..36fd3c9 100644
--- a/internal/ceres/autodiff_local_parameterization_test.cc
+++ b/internal/ceres/autodiff_local_parameterization_test.cc
@@ -28,8 +28,10 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
-#include <cmath>
 #include "ceres/autodiff_local_parameterization.h"
+
+#include <cmath>
+
 #include "ceres/local_parameterization.h"
 #include "ceres/rotation.h"
 #include "gtest/gtest.h"
@@ -48,8 +50,7 @@
 };
 
 TEST(AutoDiffLocalParameterizationTest, IdentityParameterization) {
-  AutoDiffLocalParameterization<IdentityPlus, 3, 3>
-      parameterization;
+  AutoDiffLocalParameterization<IdentityPlus, 3, 3> parameterization;
 
   double x[3] = {1.0, 2.0, 3.0};
   double delta[3] = {0.0, 1.0, 2.0};
@@ -71,9 +72,8 @@
 }
 
 struct ScaledPlus {
-  explicit ScaledPlus(const double &scale_factor)
-     : scale_factor_(scale_factor)
-  {}
+  explicit ScaledPlus(const double& scale_factor)
+      : scale_factor_(scale_factor) {}
 
   template <typename T>
   bool operator()(const T* x, const T* delta, T* x_plus_delta) const {
@@ -89,8 +89,8 @@
 TEST(AutoDiffLocalParameterizationTest, ScaledParameterization) {
   const double kTolerance = 1e-14;
 
-  AutoDiffLocalParameterization<ScaledPlus, 3, 3>
-      parameterization(new ScaledPlus(1.2345));
+  AutoDiffLocalParameterization<ScaledPlus, 3, 3> parameterization(
+      new ScaledPlus(1.2345));
 
   double x[3] = {1.0, 2.0, 3.0};
   double delta[3] = {0.0, 1.0, 2.0};
@@ -112,7 +112,7 @@
 }
 
 struct QuaternionPlus {
-  template<typename T>
+  template <typename T>
   bool operator()(const T* x, const T* delta, T* x_plus_delta) const {
     const T squared_norm_delta =
         delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2];
@@ -141,13 +141,12 @@
   }
 };
 
-void QuaternionParameterizationTestHelper(const double* x,
-                                          const double* delta) {
+static void QuaternionParameterizationTestHelper(const double* x,
+                                                 const double* delta) {
   const double kTolerance = 1e-14;
   double x_plus_delta_ref[4] = {0.0, 0.0, 0.0, 0.0};
   double jacobian_ref[12];
 
-
   QuaternionParameterization ref_parameterization;
   ref_parameterization.Plus(x, delta, x_plus_delta_ref);
   ref_parameterization.ComputeJacobian(x, jacobian_ref);
@@ -162,20 +161,22 @@
     EXPECT_NEAR(x_plus_delta[i], x_plus_delta_ref[i], kTolerance);
   }
 
+  // clang-format off
   const double x_plus_delta_norm =
       sqrt(x_plus_delta[0] * x_plus_delta[0] +
            x_plus_delta[1] * x_plus_delta[1] +
            x_plus_delta[2] * x_plus_delta[2] +
            x_plus_delta[3] * x_plus_delta[3]);
+  // clang-format on
 
   EXPECT_NEAR(x_plus_delta_norm, 1.0, kTolerance);
 
   for (int i = 0; i < 12; ++i) {
     EXPECT_TRUE(std::isfinite(jacobian[i]));
     EXPECT_NEAR(jacobian[i], jacobian_ref[i], kTolerance)
-        << "Jacobian mismatch: i = " << i
-        << "\n Expected \n" << ConstMatrixRef(jacobian_ref, 4, 3)
-        << "\n Actual \n" << ConstMatrixRef(jacobian, 4, 3);
+        << "Jacobian mismatch: i = " << i << "\n Expected \n"
+        << ConstMatrixRef(jacobian_ref, 4, 3) << "\n Actual \n"
+        << ConstMatrixRef(jacobian, 4, 3);
   }
 }
 
@@ -185,13 +186,14 @@
   QuaternionParameterizationTestHelper(x, delta);
 }
 
-
 TEST(AutoDiffLocalParameterization, QuaternionParameterizationNearZeroTest) {
   double x[4] = {0.52, 0.25, 0.15, 0.45};
+  // clang-format off
   double norm_x = sqrt(x[0] * x[0] +
                        x[1] * x[1] +
                        x[2] * x[2] +
                        x[3] * x[3]);
+  // clang-format on
   for (int i = 0; i < 4; ++i) {
     x[i] = x[i] / norm_x;
   }
@@ -206,10 +208,12 @@
 
 TEST(AutoDiffLocalParameterization, QuaternionParameterizationNonZeroTest) {
   double x[4] = {0.52, 0.25, 0.15, 0.45};
+  // clang-format off
   double norm_x = sqrt(x[0] * x[0] +
                        x[1] * x[1] +
                        x[2] * x[2] +
                        x[3] * x[3]);
+  // clang-format on
 
   for (int i = 0; i < 4; ++i) {
     x[i] = x[i] / norm_x;
diff --git a/internal/ceres/autodiff_test.cc b/internal/ceres/autodiff_test.cc
index 04a77ea..2d56400 100644
--- a/internal/ceres/autodiff_test.cc
+++ b/internal/ceres/autodiff_test.cc
@@ -30,14 +30,14 @@
 
 #include "ceres/internal/autodiff.h"
 
-#include "gtest/gtest.h"
 #include "ceres/random.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
 
-template <typename T> inline
-T &RowMajorAccess(T *base, int rows, int cols, int i, int j) {
+template <typename T>
+inline T& RowMajorAccess(T* base, int rows, int cols, int i, int j) {
   return base[cols * i + j];
 }
 
@@ -49,12 +49,12 @@
 //   bool operator()(T const *, T *) const;
 //
 // which maps a vector of parameters to a vector of outputs.
-template <typename B, typename T, int M, int N> inline
-bool SymmetricDiff(const B& b,
-                   const T par[N],
-                   T del,           // step size.
-                   T fun[M],
-                   T jac[M * N]) {  // row-major.
+template <typename B, typename T, int M, int N>
+inline bool SymmetricDiff(const B& b,
+                          const T par[N],
+                          T del,  // step size.
+                          T fun[M],
+                          T jac[M * N]) {  // row-major.
   if (!b(par, fun)) {
     return false;
   }
@@ -97,8 +97,8 @@
   return true;
 }
 
-template <typename A> inline
-void QuaternionToScaledRotation(A const q[4], A R[3 * 3]) {
+template <typename A>
+inline void QuaternionToScaledRotation(A const q[4], A R[3 * 3]) {
   // Make convenient names for elements of q.
   A a = q[0];
   A b = q[1];
@@ -106,20 +106,26 @@
   A d = q[3];
   // This is not to eliminate common sub-expression, but to
   // make the lines shorter so that they fit in 80 columns!
-  A aa = a*a;
-  A ab = a*b;
-  A ac = a*c;
-  A ad = a*d;
-  A bb = b*b;
-  A bc = b*c;
-  A bd = b*d;
-  A cc = c*c;
-  A cd = c*d;
-  A dd = d*d;
+  A aa = a * a;
+  A ab = a * b;
+  A ac = a * c;
+  A ad = a * d;
+  A bb = b * b;
+  A bc = b * c;
+  A bd = b * d;
+  A cc = c * c;
+  A cd = c * d;
+  A dd = d * d;
 #define R(i, j) RowMajorAccess(R, 3, 3, (i), (j))
-  R(0, 0) =  aa+bb-cc-dd; R(0, 1) = A(2)*(bc-ad); R(0, 2) = A(2)*(ac+bd);  // NOLINT
-  R(1, 0) = A(2)*(ad+bc); R(1, 1) =  aa-bb+cc-dd; R(1, 2) = A(2)*(cd-ab);  // NOLINT
-  R(2, 0) = A(2)*(bd-ac); R(2, 1) = A(2)*(ab+cd); R(2, 2) =  aa-bb-cc+dd;  // NOLINT
+  R(0, 0) = aa + bb - cc - dd;
+  R(0, 1) = A(2) * (bc - ad);
+  R(0, 2) = A(2) * (ac + bd);  // NOLINT
+  R(1, 0) = A(2) * (ad + bc);
+  R(1, 1) = aa - bb + cc - dd;
+  R(1, 2) = A(2) * (cd - ab);  // NOLINT
+  R(2, 0) = A(2) * (bd - ac);
+  R(2, 1) = A(2) * (ab + cd);
+  R(2, 2) = aa - bb - cc + dd;  // NOLINT
 #undef R
 }
 
@@ -171,8 +177,8 @@
   }
 
   // Handy names for the P and X parts.
-  double *P = PX + 0;
-  double *X = PX + 12;
+  double* P = PX + 0;
+  double* X = PX + 12;
 
   // Apply the mapping, to get image point b_x.
   double b_x[2];
@@ -181,8 +187,8 @@
   // Use finite differencing to estimate the Jacobian.
   double fd_x[2];
   double fd_J[2 * (12 + 4)];
-  ASSERT_TRUE((SymmetricDiff<Projective, double, 2, 12 + 4>(b, PX, del,
-                                                            fd_x, fd_J)));
+  ASSERT_TRUE(
+      (SymmetricDiff<Projective, double, 2, 12 + 4>(b, PX, del, fd_x, fd_J)));
 
   for (int i = 0; i < 2; ++i) {
     ASSERT_NEAR(fd_x[i], b_x[i], tol);
@@ -192,9 +198,9 @@
   double ad_x1[2];
   double J_PX[2 * (12 + 4)];
   {
-    double *parameters[] = { PX };
-    double *jacobians[] = { J_PX };
-    ASSERT_TRUE((AutoDifferentiate<StaticParameterDims<12 + 4>>(
+    double* parameters[] = {PX};
+    double* jacobians[] = {J_PX};
+    ASSERT_TRUE((AutoDifferentiate<2, StaticParameterDims<12 + 4>>(
         b, parameters, 2, ad_x1, jacobians)));
 
     for (int i = 0; i < 2; ++i) {
@@ -207,9 +213,9 @@
     double ad_x2[2];
     double J_P[2 * 12];
     double J_X[2 * 4];
-    double *parameters[] = { P, X };
-    double *jacobians[] = { J_P, J_X };
-    ASSERT_TRUE((AutoDifferentiate<StaticParameterDims<12, 4>>(
+    double* parameters[] = {P, X};
+    double* jacobians[] = {J_P, J_X};
+    ASSERT_TRUE((AutoDifferentiate<2, StaticParameterDims<12, 4>>(
         b, parameters, 2, ad_x2, jacobians)));
 
     for (int i = 0; i < 2; ++i) {
@@ -258,13 +264,12 @@
 
     // Set P(:, 4) = - R c
     for (int i = 0; i < 3; ++i) {
-      RowMajorAccess(P, 3, 4, i, 3) =
-        - (RowMajorAccess(R, 3, 3, i, 0) * c[0] +
-           RowMajorAccess(R, 3, 3, i, 1) * c[1] +
-           RowMajorAccess(R, 3, 3, i, 2) * c[2]);
+      RowMajorAccess(P, 3, 4, i, 3) = -(RowMajorAccess(R, 3, 3, i, 0) * c[0] +
+                                        RowMajorAccess(R, 3, 3, i, 1) * c[1] +
+                                        RowMajorAccess(R, 3, 3, i, 2) * c[2]);
     }
 
-    A X1[4] = { X[0], X[1], X[2], A(1) };
+    A X1[4] = {X[0], X[1], X[2], A(1)};
     Projective p;
     return p(P, X1, x);
   }
@@ -287,13 +292,12 @@
 
   // Make random parameter vector.
   double qcX[4 + 3 + 3];
-  for (int i = 0; i < 4 + 3 + 3; ++i)
-    qcX[i] = RandDouble();
+  for (int i = 0; i < 4 + 3 + 3; ++i) qcX[i] = RandDouble();
 
   // Handy names.
-  double *q = qcX;
-  double *c = qcX + 4;
-  double *X = qcX + 4 + 3;
+  double* q = qcX;
+  double* c = qcX + 4;
+  double* X = qcX + 4 + 3;
 
   // Compute projection, b_x.
   double b_x[2];
@@ -302,8 +306,8 @@
   // Finite differencing estimate of Jacobian.
   double fd_x[2];
   double fd_J[2 * (4 + 3 + 3)];
-  ASSERT_TRUE((SymmetricDiff<Metric, double, 2, 4 + 3 + 3>(b, qcX, del,
-                                                           fd_x, fd_J)));
+  ASSERT_TRUE(
+      (SymmetricDiff<Metric, double, 2, 4 + 3 + 3>(b, qcX, del, fd_x, fd_J)));
 
   for (int i = 0; i < 2; ++i) {
     ASSERT_NEAR(fd_x[i], b_x[i], tol);
@@ -314,9 +318,9 @@
   double J_q[2 * 4];
   double J_c[2 * 3];
   double J_X[2 * 3];
-  double *parameters[] = { q, c, X };
-  double *jacobians[] = { J_q, J_c, J_X };
-  ASSERT_TRUE((AutoDifferentiate<StaticParameterDims<4, 3, 3>>(
+  double* parameters[] = {q, c, X};
+  double* jacobians[] = {J_q, J_c, J_X};
+  ASSERT_TRUE((AutoDifferentiate<2, StaticParameterDims<4, 3, 3>>(
       b, parameters, 2, ad_x, jacobians)));
 
   for (int i = 0; i < 2; ++i) {
@@ -350,12 +354,12 @@
 };
 
 TEST(AutoDiff, VaryingNumberOfResidualsForOneCostFunctorType) {
-  double x[2] = { 1.0, 5.5 };
-  double *parameters[] = { x };
+  double x[2] = {1.0, 5.5};
+  double* parameters[] = {x};
   const int kMaxResiduals = 10;
   double J_x[2 * kMaxResiduals];
   double residuals[kMaxResiduals];
-  double *jacobians[] = { J_x };
+  double* jacobians[] = {J_x};
 
   // Use a single functor, but tweak it to produce different numbers of
   // residuals.
@@ -366,7 +370,7 @@
     functor.num_residuals = num_residuals;
 
     // Run autodiff with the new number of residuals.
-    ASSERT_TRUE((AutoDifferentiate<StaticParameterDims<2>>(
+    ASSERT_TRUE((AutoDifferentiate<DYNAMIC, StaticParameterDims<2>>(
         functor, parameters, num_residuals, residuals, jacobians)));
 
     const double kTolerance = 1e-14;
@@ -404,11 +408,8 @@
 
 struct Residual4Param {
   template <typename T>
-  bool operator()(const T* x0,
-                  const T* x1,
-                  const T* x2,
-                  const T* x3,
-                  T* y) const {
+  bool operator()(
+      const T* x0, const T* x1, const T* x2, const T* x3, T* y) const {
     y[0] = *x0 + pow(*x1, 2) + pow(*x2, 3) + pow(*x3, 4);
     return true;
   }
@@ -437,7 +438,7 @@
                   const T* x5,
                   T* y) const {
     y[0] = *x0 + pow(*x1, 2) + pow(*x2, 3) + pow(*x3, 4) + pow(*x4, 5) +
-        pow(*x5, 6);
+           pow(*x5, 6);
     return true;
   }
 };
@@ -453,7 +454,7 @@
                   const T* x6,
                   T* y) const {
     y[0] = *x0 + pow(*x1, 2) + pow(*x2, 3) + pow(*x3, 4) + pow(*x4, 5) +
-        pow(*x5, 6) + pow(*x6, 7);
+           pow(*x5, 6) + pow(*x6, 7);
     return true;
   }
 };
@@ -470,7 +471,7 @@
                   const T* x7,
                   T* y) const {
     y[0] = *x0 + pow(*x1, 2) + pow(*x2, 3) + pow(*x3, 4) + pow(*x4, 5) +
-        pow(*x5, 6) + pow(*x6, 7) + pow(*x7, 8);
+           pow(*x5, 6) + pow(*x6, 7) + pow(*x7, 8);
     return true;
   }
 };
@@ -488,7 +489,7 @@
                   const T* x8,
                   T* y) const {
     y[0] = *x0 + pow(*x1, 2) + pow(*x2, 3) + pow(*x3, 4) + pow(*x4, 5) +
-        pow(*x5, 6) + pow(*x6, 7) + pow(*x7, 8) + pow(*x8, 9);
+           pow(*x5, 6) + pow(*x6, 7) + pow(*x7, 8) + pow(*x8, 9);
     return true;
   }
 };
@@ -507,7 +508,7 @@
                   const T* x9,
                   T* y) const {
     y[0] = *x0 + pow(*x1, 2) + pow(*x2, 3) + pow(*x3, 4) + pow(*x4, 5) +
-        pow(*x5, 6) + pow(*x6, 7) + pow(*x7, 8) + pow(*x8, 9) + pow(*x9, 10);
+           pow(*x5, 6) + pow(*x6, 7) + pow(*x7, 8) + pow(*x8, 9) + pow(*x9, 10);
     return true;
   }
 };
@@ -528,7 +529,7 @@
   {
     Residual1Param functor;
     int num_variables = 1;
-    EXPECT_TRUE((AutoDifferentiate<StaticParameterDims<1>>(
+    EXPECT_TRUE((AutoDifferentiate<1, StaticParameterDims<1>>(
         functor, parameters, 1, &residual, jacobians)));
     EXPECT_EQ(residual, pow(2, num_variables + 1) - 2);
     for (int i = 0; i < num_variables; ++i) {
@@ -539,7 +540,7 @@
   {
     Residual2Param functor;
     int num_variables = 2;
-    EXPECT_TRUE((AutoDifferentiate<StaticParameterDims<1, 1>>(
+    EXPECT_TRUE((AutoDifferentiate<1, StaticParameterDims<1, 1>>(
         functor, parameters, 1, &residual, jacobians)));
     EXPECT_EQ(residual, pow(2, num_variables + 1) - 2);
     for (int i = 0; i < num_variables; ++i) {
@@ -550,7 +551,7 @@
   {
     Residual3Param functor;
     int num_variables = 3;
-    EXPECT_TRUE((AutoDifferentiate<StaticParameterDims<1, 1, 1>>(
+    EXPECT_TRUE((AutoDifferentiate<1, StaticParameterDims<1, 1, 1>>(
         functor, parameters, 1, &residual, jacobians)));
     EXPECT_EQ(residual, pow(2, num_variables + 1) - 2);
     for (int i = 0; i < num_variables; ++i) {
@@ -561,7 +562,7 @@
   {
     Residual4Param functor;
     int num_variables = 4;
-    EXPECT_TRUE((AutoDifferentiate<StaticParameterDims<1, 1, 1, 1>>(
+    EXPECT_TRUE((AutoDifferentiate<1, StaticParameterDims<1, 1, 1, 1>>(
         functor, parameters, 1, &residual, jacobians)));
     EXPECT_EQ(residual, pow(2, num_variables + 1) - 2);
     for (int i = 0; i < num_variables; ++i) {
@@ -572,7 +573,7 @@
   {
     Residual5Param functor;
     int num_variables = 5;
-    EXPECT_TRUE((AutoDifferentiate<StaticParameterDims<1, 1, 1, 1, 1>>(
+    EXPECT_TRUE((AutoDifferentiate<1, StaticParameterDims<1, 1, 1, 1, 1>>(
         functor, parameters, 1, &residual, jacobians)));
     EXPECT_EQ(residual, pow(2, num_variables + 1) - 2);
     for (int i = 0; i < num_variables; ++i) {
@@ -583,7 +584,7 @@
   {
     Residual6Param functor;
     int num_variables = 6;
-    EXPECT_TRUE((AutoDifferentiate<StaticParameterDims<1, 1, 1, 1, 1, 1>>(
+    EXPECT_TRUE((AutoDifferentiate<1, StaticParameterDims<1, 1, 1, 1, 1, 1>>(
         functor, parameters, 1, &residual, jacobians)));
     EXPECT_EQ(residual, pow(2, num_variables + 1) - 2);
     for (int i = 0; i < num_variables; ++i) {
@@ -594,7 +595,7 @@
   {
     Residual7Param functor;
     int num_variables = 7;
-    EXPECT_TRUE((AutoDifferentiate<StaticParameterDims<1, 1, 1, 1, 1, 1, 1>>(
+    EXPECT_TRUE((AutoDifferentiate<1, StaticParameterDims<1, 1, 1, 1, 1, 1, 1>>(
         functor, parameters, 1, &residual, jacobians)));
     EXPECT_EQ(residual, pow(2, num_variables + 1) - 2);
     for (int i = 0; i < num_variables; ++i) {
@@ -605,8 +606,9 @@
   {
     Residual8Param functor;
     int num_variables = 8;
-    EXPECT_TRUE((AutoDifferentiate<StaticParameterDims<1, 1, 1, 1, 1, 1, 1, 1>>(
-        functor, parameters, 1, &residual, jacobians)));
+    EXPECT_TRUE(
+        (AutoDifferentiate<1, StaticParameterDims<1, 1, 1, 1, 1, 1, 1, 1>>(
+            functor, parameters, 1, &residual, jacobians)));
     EXPECT_EQ(residual, pow(2, num_variables + 1) - 2);
     for (int i = 0; i < num_variables; ++i) {
       EXPECT_EQ(jacobian_values[i], (i + 1) * pow(2, i));
@@ -617,7 +619,7 @@
     Residual9Param functor;
     int num_variables = 9;
     EXPECT_TRUE(
-        (AutoDifferentiate<StaticParameterDims<1, 1, 1, 1, 1, 1, 1, 1, 1>>(
+        (AutoDifferentiate<1, StaticParameterDims<1, 1, 1, 1, 1, 1, 1, 1, 1>>(
             functor, parameters, 1, &residual, jacobians)));
     EXPECT_EQ(residual, pow(2, num_variables + 1) - 2);
     for (int i = 0; i < num_variables; ++i) {
@@ -628,8 +630,8 @@
   {
     Residual10Param functor;
     int num_variables = 10;
-    EXPECT_TRUE(
-        (AutoDifferentiate<StaticParameterDims<1, 1, 1, 1, 1, 1, 1, 1, 1, 1>>(
+    EXPECT_TRUE((
+        AutoDifferentiate<1, StaticParameterDims<1, 1, 1, 1, 1, 1, 1, 1, 1, 1>>(
             functor, parameters, 1, &residual, jacobians)));
     EXPECT_EQ(residual, pow(2, num_variables + 1) - 2);
     for (int i = 0; i < num_variables; ++i) {
diff --git a/internal/ceres/blas.cc b/internal/ceres/blas.cc
index 3ba63bb..f8d006e 100644
--- a/internal/ceres/blas.cc
+++ b/internal/ceres/blas.cc
@@ -29,6 +29,7 @@
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
 #include "ceres/blas.h"
+
 #include "ceres/internal/port.h"
 #include "glog/logging.h"
 
diff --git a/internal/ceres/block_evaluate_preparer.cc b/internal/ceres/block_evaluate_preparer.cc
index 59c0d3e..7db96d9 100644
--- a/internal/ceres/block_evaluate_preparer.cc
+++ b/internal/ceres/block_evaluate_preparer.cc
@@ -31,6 +31,7 @@
 #include "ceres/block_evaluate_preparer.h"
 
 #include <vector>
+
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/casts.h"
 #include "ceres/parameter_block.h"
@@ -53,10 +54,8 @@
                                     double** jacobians) {
   // If the overall jacobian is not available, use the scratch space.
   if (jacobian == NULL) {
-    scratch_evaluate_preparer_.Prepare(residual_block,
-                                       residual_block_index,
-                                       jacobian,
-                                       jacobians);
+    scratch_evaluate_preparer_.Prepare(
+        residual_block, residual_block_index, jacobian, jacobians);
     return;
   }
 
diff --git a/internal/ceres/block_jacobi_preconditioner.cc b/internal/ceres/block_jacobi_preconditioner.cc
index 772c7af..6f37aca 100644
--- a/internal/ceres/block_jacobi_preconditioner.cc
+++ b/internal/ceres/block_jacobi_preconditioner.cc
@@ -30,9 +30,9 @@
 
 #include "ceres/block_jacobi_preconditioner.h"
 
+#include "ceres/block_random_access_diagonal_matrix.h"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/block_structure.h"
-#include "ceres/block_random_access_diagonal_matrix.h"
 #include "ceres/casts.h"
 #include "ceres/internal/eigen.h"
 
@@ -65,13 +65,11 @@
       const int col_block_size = bs->cols[block_id].size;
 
       int r, c, row_stride, col_stride;
-      CellInfo* cell_info = m_->GetCell(block_id, block_id,
-                                        &r, &c,
-                                        &row_stride, &col_stride);
+      CellInfo* cell_info =
+          m_->GetCell(block_id, block_id, &r, &c, &row_stride, &col_stride);
       MatrixRef m(cell_info->values, row_stride, col_stride);
-      ConstMatrixRef b(values + cells[j].position,
-                       row_block_size,
-                       col_block_size);
+      ConstMatrixRef b(
+          values + cells[j].position, row_block_size, col_block_size);
       m.block(r, c, col_block_size, col_block_size) += b.transpose() * b;
     }
   }
@@ -82,9 +80,7 @@
     for (int i = 0; i < bs->cols.size(); ++i) {
       const int block_size = bs->cols[i].size;
       int r, c, row_stride, col_stride;
-      CellInfo* cell_info = m_->GetCell(i, i,
-                                        &r, &c,
-                                        &row_stride, &col_stride);
+      CellInfo* cell_info = m_->GetCell(i, i, &r, &c, &row_stride, &col_stride);
       MatrixRef m(cell_info->values, row_stride, col_stride);
       m.block(r, c, block_size, block_size).diagonal() +=
           ConstVectorRef(D + position, block_size).array().square().matrix();
diff --git a/internal/ceres/block_jacobi_preconditioner.h b/internal/ceres/block_jacobi_preconditioner.h
index a6d19e8..18f7495 100644
--- a/internal/ceres/block_jacobi_preconditioner.h
+++ b/internal/ceres/block_jacobi_preconditioner.h
@@ -32,7 +32,9 @@
 #define CERES_INTERNAL_BLOCK_JACOBI_PRECONDITIONER_H_
 
 #include <memory>
+
 #include "ceres/block_random_access_diagonal_matrix.h"
+#include "ceres/internal/port.h"
 #include "ceres/preconditioner.h"
 
 namespace ceres {
@@ -51,7 +53,8 @@
 // update the matrix by running Update(A, D). The values of the matrix A are
 // inspected to construct the preconditioner. The vector D is applied as the
 // D^TD diagonal term.
-class BlockJacobiPreconditioner : public BlockSparseMatrixPreconditioner {
+class CERES_EXPORT_INTERNAL BlockJacobiPreconditioner
+    : public BlockSparseMatrixPreconditioner {
  public:
   // A must remain valid while the BlockJacobiPreconditioner is.
   explicit BlockJacobiPreconditioner(const BlockSparseMatrix& A);
@@ -61,13 +64,13 @@
   virtual ~BlockJacobiPreconditioner();
 
   // Preconditioner interface
-  virtual void RightMultiply(const double* x, double* y) const;
-  virtual int num_rows() const { return m_->num_rows(); }
-  virtual int num_cols() const { return m_->num_rows(); }
+  void RightMultiply(const double* x, double* y) const final;
+  int num_rows() const final { return m_->num_rows(); }
+  int num_cols() const final { return m_->num_rows(); }
   const BlockRandomAccessDiagonalMatrix& matrix() const { return *m_; }
 
  private:
-  virtual bool UpdateImpl(const BlockSparseMatrix& A, const double* D);
+  bool UpdateImpl(const BlockSparseMatrix& A, const double* D) final;
 
   std::unique_ptr<BlockRandomAccessDiagonalMatrix> m_;
 };
diff --git a/internal/ceres/block_jacobi_preconditioner_test.cc b/internal/ceres/block_jacobi_preconditioner_test.cc
index 4a9a871..cc582c6 100644
--- a/internal/ceres/block_jacobi_preconditioner_test.cc
+++ b/internal/ceres/block_jacobi_preconditioner_test.cc
@@ -32,16 +32,16 @@
 
 #include <memory>
 #include <vector>
-#include "ceres/block_random_access_diagonal_matrix.h"
-#include "ceres/linear_least_squares_problems.h"
-#include "ceres/block_sparse_matrix.h"
-#include "gtest/gtest.h"
+
 #include "Eigen/Dense"
+#include "ceres/block_random_access_diagonal_matrix.h"
+#include "ceres/block_sparse_matrix.h"
+#include "ceres/linear_least_squares_problems.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
 
-
 class BlockJacobiPreconditionerTest : public ::testing::Test {
  protected:
   void SetUpFromProblemId(int problem_id) {
@@ -56,7 +56,10 @@
     A->ToDenseMatrix(&dense_a);
     dense_ata = dense_a.transpose() * dense_a;
     dense_ata += VectorRef(D.get(), A->num_cols())
-        .array().square().matrix().asDiagonal();
+                     .array()
+                     .square()
+                     .matrix()
+                     .asDiagonal();
   }
 
   void VerifyDiagonalBlocks(const int problem_id) {
@@ -73,17 +76,14 @@
     for (int i = 0; i < bs->cols.size(); ++i) {
       const int block_size = bs->cols[i].size;
       int r, c, row_stride, col_stride;
-      CellInfo* cell_info = m->GetCell(i, i,
-                                       &r, &c,
-                                       &row_stride, &col_stride);
+      CellInfo* cell_info = m->GetCell(i, i, &r, &c, &row_stride, &col_stride);
       MatrixRef m(cell_info->values, row_stride, col_stride);
       Matrix actual_block_inverse = m.block(r, c, block_size, block_size);
-      Matrix expected_block = dense_ata.block(bs->cols[i].position,
-                                              bs->cols[i].position,
-                                              block_size,
-                                              block_size);
+      Matrix expected_block = dense_ata.block(
+          bs->cols[i].position, bs->cols[i].position, block_size, block_size);
       const double residual = (actual_block_inverse * expected_block -
-                               Matrix::Identity(block_size, block_size)).norm();
+                               Matrix::Identity(block_size, block_size))
+                                  .norm();
       EXPECT_NEAR(residual, 0.0, 1e-12) << "Block: " << i;
     }
   }
@@ -93,13 +93,9 @@
   Matrix dense_ata;
 };
 
-TEST_F(BlockJacobiPreconditionerTest, SmallProblem) {
-  VerifyDiagonalBlocks(2);
-}
+TEST_F(BlockJacobiPreconditionerTest, SmallProblem) { VerifyDiagonalBlocks(2); }
 
-TEST_F(BlockJacobiPreconditionerTest, LargeProblem) {
-  VerifyDiagonalBlocks(3);
-}
+TEST_F(BlockJacobiPreconditionerTest, LargeProblem) { VerifyDiagonalBlocks(3); }
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/block_jacobian_writer.cc b/internal/ceres/block_jacobian_writer.cc
index 6998bd6..17c157b 100644
--- a/internal/ceres/block_jacobian_writer.cc
+++ b/internal/ceres/block_jacobian_writer.cc
@@ -32,11 +32,11 @@
 
 #include "ceres/block_evaluate_preparer.h"
 #include "ceres/block_sparse_matrix.h"
+#include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
 #include "ceres/parameter_block.h"
 #include "ceres/program.h"
 #include "ceres/residual_block.h"
-#include "ceres/internal/eigen.h"
-#include "ceres/internal/port.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/block_jacobian_writer.h b/internal/ceres/block_jacobian_writer.h
index c94a0d3..8054d7b 100644
--- a/internal/ceres/block_jacobian_writer.h
+++ b/internal/ceres/block_jacobian_writer.h
@@ -39,6 +39,7 @@
 #define CERES_INTERNAL_BLOCK_JACOBIAN_WRITER_H_
 
 #include <vector>
+
 #include "ceres/evaluator.h"
 #include "ceres/internal/port.h"
 
@@ -52,8 +53,7 @@
 // TODO(sameeragarwal): This class needs documemtation.
 class BlockJacobianWriter {
  public:
-  BlockJacobianWriter(const Evaluator::Options& options,
-                      Program* program);
+  BlockJacobianWriter(const Evaluator::Options& options, Program* program);
 
   // JacobianWriter interface.
 
diff --git a/internal/ceres/block_random_access_dense_matrix.cc b/internal/ceres/block_random_access_dense_matrix.cc
index f567aa5..386f81e 100644
--- a/internal/ceres/block_random_access_dense_matrix.cc
+++ b/internal/ceres/block_random_access_dense_matrix.cc
@@ -31,6 +31,7 @@
 #include "ceres/block_random_access_dense_matrix.h"
 
 #include <vector>
+
 #include "ceres/internal/eigen.h"
 #include "glog/logging.h"
 
@@ -59,8 +60,7 @@
 
 // Assume that the user does not hold any locks on any cell blocks
 // when they are calling SetZero.
-BlockRandomAccessDenseMatrix::~BlockRandomAccessDenseMatrix() {
-}
+BlockRandomAccessDenseMatrix::~BlockRandomAccessDenseMatrix() {}
 
 CellInfo* BlockRandomAccessDenseMatrix::GetCell(const int row_block_id,
                                                 const int col_block_id,
diff --git a/internal/ceres/block_random_access_dense_matrix.h b/internal/ceres/block_random_access_dense_matrix.h
index e1dca84..9e55524 100644
--- a/internal/ceres/block_random_access_dense_matrix.h
+++ b/internal/ceres/block_random_access_dense_matrix.h
@@ -31,11 +31,10 @@
 #ifndef CERES_INTERNAL_BLOCK_RANDOM_ACCESS_DENSE_MATRIX_H_
 #define CERES_INTERNAL_BLOCK_RANDOM_ACCESS_DENSE_MATRIX_H_
 
-#include "ceres/block_random_access_matrix.h"
-
 #include <memory>
 #include <vector>
 
+#include "ceres/block_random_access_matrix.h"
 #include "ceres/internal/port.h"
 
 namespace ceres {
@@ -51,7 +50,8 @@
 // pair.
 //
 // ReturnCell is a nop.
-class BlockRandomAccessDenseMatrix : public BlockRandomAccessMatrix {
+class CERES_EXPORT_INTERNAL BlockRandomAccessDenseMatrix
+    : public BlockRandomAccessMatrix {
  public:
   // blocks is a vector of block sizes. The resulting matrix has
   // blocks.size() * blocks.size() cells.
@@ -64,21 +64,21 @@
   virtual ~BlockRandomAccessDenseMatrix();
 
   // BlockRandomAccessMatrix interface.
-  virtual CellInfo* GetCell(int row_block_id,
-                            int col_block_id,
-                            int* row,
-                            int* col,
-                            int* row_stride,
-                            int* col_stride);
+  CellInfo* GetCell(int row_block_id,
+                    int col_block_id,
+                    int* row,
+                    int* col,
+                    int* row_stride,
+                    int* col_stride) final;
 
   // This is not a thread safe method, it assumes that no cell is
   // locked.
-  virtual void SetZero();
+  void SetZero() final;
 
   // Since the matrix is square with the same row and column block
   // structure, num_rows() = num_cols().
-  virtual int num_rows() const { return num_rows_; }
-  virtual int num_cols() const { return num_rows_; }
+  int num_rows() const final { return num_rows_; }
+  int num_cols() const final { return num_rows_; }
 
   // The underlying matrix storing the cells.
   const double* values() const { return values_.get(); }
diff --git a/internal/ceres/block_random_access_dense_matrix_test.cc b/internal/ceres/block_random_access_dense_matrix_test.cc
index 8a5ba59..0736d56 100644
--- a/internal/ceres/block_random_access_dense_matrix_test.cc
+++ b/internal/ceres/block_random_access_dense_matrix_test.cc
@@ -28,10 +28,12 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
-#include <vector>
-#include "gtest/gtest.h"
 #include "ceres/block_random_access_dense_matrix.h"
+
+#include <vector>
+
 #include "ceres/internal/eigen.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
@@ -54,8 +56,7 @@
       int col;
       int row_stride;
       int col_stride;
-      CellInfo* cell =
-          m.GetCell(i, j, &row, &col, &row_stride, &col_stride);
+      CellInfo* cell = m.GetCell(i, j, &row, &col, &row_stride, &col_stride);
 
       EXPECT_TRUE(cell != NULL);
       EXPECT_EQ(row, row_idx);
@@ -84,11 +85,10 @@
       int col;
       int row_stride;
       int col_stride;
-      CellInfo* cell = m.GetCell(
-          i, j, &row, &col, &row_stride, &col_stride);
-      MatrixRef(cell->values, row_stride, col_stride).block(
-          row, col, blocks[i], blocks[j]) =
-          (i+1) * (j+1) * Matrix::Ones(blocks[i], blocks[j]);
+      CellInfo* cell = m.GetCell(i, j, &row, &col, &row_stride, &col_stride);
+      MatrixRef(cell->values, row_stride, col_stride)
+          .block(row, col, blocks[i], blocks[j]) =
+          (i + 1) * (j + 1) * Matrix::Ones(blocks[i], blocks[j]);
     }
   }
 
diff --git a/internal/ceres/block_random_access_diagonal_matrix.cc b/internal/ceres/block_random_access_diagonal_matrix.cc
index 526d173..08f6d7f 100644
--- a/internal/ceres/block_random_access_diagonal_matrix.cc
+++ b/internal/ceres/block_random_access_diagonal_matrix.cc
@@ -63,9 +63,8 @@
     num_nonzeros += blocks_[i] * blocks_[i];
   }
 
-  VLOG(1) << "Matrix Size [" << num_cols
-          << "," << num_cols
-          << "] " << num_nonzeros;
+  VLOG(1) << "Matrix Size [" << num_cols << "," << num_cols << "] "
+          << num_nonzeros;
 
   tsm_.reset(new TripletSparseMatrix(num_cols, num_cols, num_nonzeros));
   tsm_->set_num_nonzeros(num_nonzeros);
@@ -116,8 +115,7 @@
 // when they are calling SetZero.
 void BlockRandomAccessDiagonalMatrix::SetZero() {
   if (tsm_->num_nonzeros()) {
-    VectorRef(tsm_->mutable_values(),
-              tsm_->num_nonzeros()).setZero();
+    VectorRef(tsm_->mutable_values(), tsm_->num_nonzeros()).setZero();
   }
 }
 
@@ -126,11 +124,8 @@
   for (int i = 0; i < blocks_.size(); ++i) {
     const int block_size = blocks_[i];
     MatrixRef block(values, block_size, block_size);
-    block =
-        block
-        .selfadjointView<Eigen::Upper>()
-        .llt()
-        .solve(Matrix::Identity(block_size, block_size));
+    block = block.selfadjointView<Eigen::Upper>().llt().solve(
+        Matrix::Identity(block_size, block_size));
     values += block_size * block_size;
   }
 }
diff --git a/internal/ceres/block_random_access_diagonal_matrix.h b/internal/ceres/block_random_access_diagonal_matrix.h
index 6ad976f..3fe7c1e 100644
--- a/internal/ceres/block_random_access_diagonal_matrix.h
+++ b/internal/ceres/block_random_access_diagonal_matrix.h
@@ -46,11 +46,13 @@
 
 // A thread safe block diagonal matrix implementation of
 // BlockRandomAccessMatrix.
-class BlockRandomAccessDiagonalMatrix : public BlockRandomAccessMatrix {
+class CERES_EXPORT_INTERNAL BlockRandomAccessDiagonalMatrix
+    : public BlockRandomAccessMatrix {
  public:
   // blocks is an array of block sizes.
   explicit BlockRandomAccessDiagonalMatrix(const std::vector<int>& blocks);
-  BlockRandomAccessDiagonalMatrix(const BlockRandomAccessDiagonalMatrix&) = delete;
+  BlockRandomAccessDiagonalMatrix(const BlockRandomAccessDiagonalMatrix&) =
+      delete;
   void operator=(const BlockRandomAccessDiagonalMatrix&) = delete;
 
   // The destructor is not thread safe. It assumes that no one is
@@ -58,16 +60,16 @@
   virtual ~BlockRandomAccessDiagonalMatrix();
 
   // BlockRandomAccessMatrix Interface.
-  virtual CellInfo* GetCell(int row_block_id,
-                            int col_block_id,
-                            int* row,
-                            int* col,
-                            int* row_stride,
-                            int* col_stride);
+  CellInfo* GetCell(int row_block_id,
+                    int col_block_id,
+                    int* row,
+                    int* col,
+                    int* row_stride,
+                    int* col_stride) final;
 
   // This is not a thread safe method, it assumes that no cell is
   // locked.
-  virtual void SetZero();
+  void SetZero() final;
 
   // Invert the matrix assuming that each block is positive definite.
   void Invert();
@@ -76,8 +78,8 @@
   void RightMultiply(const double* x, double* y) const;
 
   // Since the matrix is square, num_rows() == num_cols().
-  virtual int num_rows() const { return tsm_->num_rows(); }
-  virtual int num_cols() const { return tsm_->num_cols(); }
+  int num_rows() const final { return tsm_->num_rows(); }
+  int num_cols() const final { return tsm_->num_cols(); }
 
   const TripletSparseMatrix* matrix() const { return tsm_.get(); }
   TripletSparseMatrix* mutable_matrix() { return tsm_.get(); }
diff --git a/internal/ceres/block_random_access_diagonal_matrix_test.cc b/internal/ceres/block_random_access_diagonal_matrix_test.cc
index a54595c..e384dac 100644
--- a/internal/ceres/block_random_access_diagonal_matrix_test.cc
+++ b/internal/ceres/block_random_access_diagonal_matrix_test.cc
@@ -28,15 +28,16 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/block_random_access_diagonal_matrix.h"
+
 #include <limits>
 #include <memory>
 #include <vector>
 
-#include "ceres/block_random_access_diagonal_matrix.h"
+#include "Eigen/Cholesky"
 #include "ceres/internal/eigen.h"
 #include "glog/logging.h"
 #include "gtest/gtest.h"
-#include "Eigen/Cholesky"
 
 namespace ceres {
 namespace internal {
@@ -49,7 +50,7 @@
     blocks.push_back(4);
     blocks.push_back(5);
     const int num_rows = 3 + 4 + 5;
-    num_nonzeros_ =  3 * 3 + 4 * 4 + 5 * 5;
+    num_nonzeros_ = 3 * 3 + 4 * 4 + 5 * 5;
 
     m_.reset(new BlockRandomAccessDiagonalMatrix(blocks));
 
@@ -66,9 +67,8 @@
 
       for (int j = 0; j < blocks.size(); ++j) {
         col_block_id = j;
-        CellInfo* cell =  m_->GetCell(row_block_id, col_block_id,
-                                    &row, &col,
-                                    &row_stride, &col_stride);
+        CellInfo* cell = m_->GetCell(
+            row_block_id, col_block_id, &row, &col, &row_stride, &col_stride);
         // Off diagonal entries are not present.
         if (i != j) {
           EXPECT_TRUE(cell == NULL);
@@ -82,11 +82,11 @@
         EXPECT_EQ(col_stride, blocks[col_block_id]);
 
         // Write into the block
-        MatrixRef(cell->values, row_stride, col_stride).block(
-            row, col, blocks[row_block_id], blocks[col_block_id]) =
-            (row_block_id + 1) * (col_block_id +1) *
-            Matrix::Ones(blocks[row_block_id], blocks[col_block_id])
-            + Matrix::Identity(blocks[row_block_id], blocks[row_block_id]);
+        MatrixRef(cell->values, row_stride, col_stride)
+            .block(row, col, blocks[row_block_id], blocks[col_block_id]) =
+            (row_block_id + 1) * (col_block_id + 1) *
+                Matrix::Ones(blocks[row_block_id], blocks[col_block_id]) +
+            Matrix::Identity(blocks[row_block_id], blocks[row_block_id]);
       }
     }
   }
@@ -107,28 +107,31 @@
   double kTolerance = 1e-14;
 
   // (0,0)
-  EXPECT_NEAR((dense.block(0, 0, 3, 3) -
-               (Matrix::Ones(3, 3) + Matrix::Identity(3, 3))).norm(),
-              0.0,
-              kTolerance);
+  EXPECT_NEAR(
+      (dense.block(0, 0, 3, 3) - (Matrix::Ones(3, 3) + Matrix::Identity(3, 3)))
+          .norm(),
+      0.0,
+      kTolerance);
 
   // (1,1)
   EXPECT_NEAR((dense.block(3, 3, 4, 4) -
-               (2 * 2 * Matrix::Ones(4, 4) + Matrix::Identity(4, 4))).norm(),
+               (2 * 2 * Matrix::Ones(4, 4) + Matrix::Identity(4, 4)))
+                  .norm(),
               0.0,
               kTolerance);
 
   // (1,1)
   EXPECT_NEAR((dense.block(7, 7, 5, 5) -
-               (3 * 3 * Matrix::Ones(5, 5) + Matrix::Identity(5, 5))).norm(),
+               (3 * 3 * Matrix::Ones(5, 5) + Matrix::Identity(5, 5)))
+                  .norm(),
               0.0,
               kTolerance);
 
   // There is nothing else in the matrix besides these four blocks.
-  EXPECT_NEAR(dense.norm(),
-              sqrt(6 * 1.0 + 3 * 4.0 +
-                   12 * 16.0 + 4 * 25.0 +
-                   20 * 81.0 + 5 * 100.0), kTolerance);
+  EXPECT_NEAR(
+      dense.norm(),
+      sqrt(6 * 1.0 + 3 * 4.0 + 12 * 16.0 + 4 * 25.0 + 20 * 81.0 + 5 * 100.0),
+      kTolerance);
 }
 
 TEST_F(BlockRandomAccessDiagonalMatrixTest, RightMultiply) {
@@ -139,7 +142,7 @@
   Vector x = Vector::Random(dense.rows());
   Vector expected_y = dense * x;
   Vector actual_y = Vector::Zero(dense.rows());
-  m_->RightMultiply(x.data(),  actual_y.data());
+  m_->RightMultiply(x.data(), actual_y.data());
   EXPECT_NEAR((expected_y - actual_y).norm(), 0, kTolerance);
 }
 
diff --git a/internal/ceres/block_random_access_matrix.cc b/internal/ceres/block_random_access_matrix.cc
index 347d765..ea88855 100644
--- a/internal/ceres/block_random_access_matrix.cc
+++ b/internal/ceres/block_random_access_matrix.cc
@@ -33,8 +33,7 @@
 namespace ceres {
 namespace internal {
 
-BlockRandomAccessMatrix::~BlockRandomAccessMatrix() {
-}
+BlockRandomAccessMatrix::~BlockRandomAccessMatrix() {}
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/block_random_access_matrix.h b/internal/ceres/block_random_access_matrix.h
index 2187fcd..f190622 100644
--- a/internal/ceres/block_random_access_matrix.h
+++ b/internal/ceres/block_random_access_matrix.h
@@ -35,6 +35,8 @@
 
 #include <mutex>
 
+#include "ceres/internal/port.h"
+
 namespace ceres {
 namespace internal {
 
@@ -84,19 +86,14 @@
 // Structure to carry a pointer to the array containing a cell and the
 // mutex guarding it.
 struct CellInfo {
-  CellInfo()
-      : values(NULL) {
-  }
-
-  explicit CellInfo(double* ptr)
-      : values(ptr) {
-  }
+  CellInfo() : values(nullptr) {}
+  explicit CellInfo(double* values) : values(values) {}
 
   double* values;
   std::mutex m;
 };
 
-class BlockRandomAccessMatrix {
+class CERES_EXPORT_INTERNAL BlockRandomAccessMatrix {
  public:
   virtual ~BlockRandomAccessMatrix();
 
diff --git a/internal/ceres/block_random_access_sparse_matrix.cc b/internal/ceres/block_random_access_sparse_matrix.cc
index 9c16454..c28b7ce 100644
--- a/internal/ceres/block_random_access_sparse_matrix.cc
+++ b/internal/ceres/block_random_access_sparse_matrix.cc
@@ -50,10 +50,8 @@
 using std::vector;
 
 BlockRandomAccessSparseMatrix::BlockRandomAccessSparseMatrix(
-    const vector<int>& blocks,
-    const set<pair<int, int>>& block_pairs)
-    : kMaxRowBlocks(10 * 1000 * 1000),
-      blocks_(blocks) {
+    const vector<int>& blocks, const set<pair<int, int>>& block_pairs)
+    : kMaxRowBlocks(10 * 1000 * 1000), blocks_(blocks) {
   CHECK_LT(blocks.size(), kMaxRowBlocks);
 
   // Build the row/column layout vector and count the number of scalar
@@ -75,9 +73,8 @@
     num_nonzeros += row_block_size * col_block_size;
   }
 
-  VLOG(1) << "Matrix Size [" << num_cols
-          << "," << num_cols
-          << "] " << num_nonzeros;
+  VLOG(1) << "Matrix Size [" << num_cols << "," << num_cols << "] "
+          << num_nonzeros;
 
   tsm_.reset(new TripletSparseMatrix(num_cols, num_cols, num_nonzeros));
   tsm_->set_num_nonzeros(num_nonzeros);
@@ -105,11 +102,11 @@
         layout_[IntPairToLong(row_block_id, col_block_id)]->values - values;
     for (int r = 0; r < row_block_size; ++r) {
       for (int c = 0; c < col_block_size; ++c, ++pos) {
-          rows[pos] = block_positions_[row_block_id] + r;
-          cols[pos] = block_positions_[col_block_id] + c;
-          values[pos] = 1.0;
-          DCHECK_LT(rows[pos], tsm_->num_rows());
-          DCHECK_LT(cols[pos], tsm_->num_rows());
+        rows[pos] = block_positions_[row_block_id] + r;
+        cols[pos] = block_positions_[col_block_id] + c;
+        values[pos] = 1.0;
+        DCHECK_LT(rows[pos], tsm_->num_rows());
+        DCHECK_LT(cols[pos], tsm_->num_rows());
       }
     }
   }
@@ -129,7 +126,7 @@
                                                  int* col,
                                                  int* row_stride,
                                                  int* col_stride) {
-  const LayoutType::iterator it  =
+  const LayoutType::iterator it =
       layout_.find(IntPairToLong(row_block_id, col_block_id));
   if (it == layout_.end()) {
     return NULL;
@@ -147,8 +144,7 @@
 // when they are calling SetZero.
 void BlockRandomAccessSparseMatrix::SetZero() {
   if (tsm_->num_nonzeros()) {
-    VectorRef(tsm_->mutable_values(),
-              tsm_->num_nonzeros()).setZero();
+    VectorRef(tsm_->mutable_values(), tsm_->num_nonzeros()).setZero();
   }
 }
 
@@ -164,7 +160,9 @@
     const int col_block_pos = block_positions_[col];
 
     MatrixVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
-        cell_position_and_data.second, row_block_size, col_block_size,
+        cell_position_and_data.second,
+        row_block_size,
+        col_block_size,
         x + col_block_pos,
         y + row_block_pos);
 
@@ -174,7 +172,9 @@
     // triangular multiply also.
     if (row != col) {
       MatrixTransposeVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
-          cell_position_and_data.second, row_block_size, col_block_size,
+          cell_position_and_data.second,
+          row_block_size,
+          col_block_size,
           x + row_block_pos,
           y + col_block_pos);
     }
diff --git a/internal/ceres/block_random_access_sparse_matrix.h b/internal/ceres/block_random_access_sparse_matrix.h
index 12244a5..0e58bbb 100644
--- a/internal/ceres/block_random_access_sparse_matrix.h
+++ b/internal/ceres/block_random_access_sparse_matrix.h
@@ -39,10 +39,10 @@
 #include <vector>
 
 #include "ceres/block_random_access_matrix.h"
-#include "ceres/triplet_sparse_matrix.h"
 #include "ceres/internal/port.h"
-#include "ceres/types.h"
 #include "ceres/small_blas.h"
+#include "ceres/triplet_sparse_matrix.h"
+#include "ceres/types.h"
 
 namespace ceres {
 namespace internal {
@@ -51,7 +51,8 @@
 // BlockRandomAccessMatrix. Internally a TripletSparseMatrix is used
 // for doing the actual storage. This class augments this matrix with
 // an unordered_map that allows random read/write access.
-class BlockRandomAccessSparseMatrix : public BlockRandomAccessMatrix {
+class CERES_EXPORT_INTERNAL BlockRandomAccessSparseMatrix
+    : public BlockRandomAccessMatrix {
  public:
   // blocks is an array of block sizes. block_pairs is a set of
   // <row_block_id, col_block_id> pairs to identify the non-zero cells
@@ -67,16 +68,16 @@
   virtual ~BlockRandomAccessSparseMatrix();
 
   // BlockRandomAccessMatrix Interface.
-  virtual CellInfo* GetCell(int row_block_id,
-                            int col_block_id,
-                            int* row,
-                            int* col,
-                            int* row_stride,
-                            int* col_stride);
+  CellInfo* GetCell(int row_block_id,
+                    int col_block_id,
+                    int* row,
+                    int* col,
+                    int* row_stride,
+                    int* col_stride) final;
 
   // This is not a thread safe method, it assumes that no cell is
   // locked.
-  virtual void SetZero();
+  void SetZero() final;
 
   // Assume that the matrix is symmetric and only one half of the
   // matrix is stored.
@@ -85,8 +86,8 @@
   void SymmetricRightMultiply(const double* x, double* y) const;
 
   // Since the matrix is square, num_rows() == num_cols().
-  virtual int num_rows() const { return tsm_->num_rows(); }
-  virtual int num_cols() const { return tsm_->num_cols(); }
+  int num_rows() const final { return tsm_->num_rows(); }
+  int num_cols() const final { return tsm_->num_cols(); }
 
   // Access to the underlying matrix object.
   const TripletSparseMatrix* matrix() const { return tsm_.get(); }
@@ -110,7 +111,7 @@
 
   // A mapping from <row_block_id, col_block_id> to the position in
   // the values array of tsm_ where the block is stored.
-  typedef std::unordered_map<long int, CellInfo* > LayoutType;
+  typedef std::unordered_map<long int, CellInfo*> LayoutType;
   LayoutType layout_;
 
   // In order traversal of contents of the matrix. This allows us to
diff --git a/internal/ceres/block_random_access_sparse_matrix_test.cc b/internal/ceres/block_random_access_sparse_matrix_test.cc
index 9ca9c46..557b678 100644
--- a/internal/ceres/block_random_access_sparse_matrix_test.cc
+++ b/internal/ceres/block_random_access_sparse_matrix_test.cc
@@ -28,11 +28,12 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/block_random_access_sparse_matrix.h"
+
 #include <limits>
 #include <memory>
 #include <vector>
 
-#include "ceres/block_random_access_sparse_matrix.h"
 #include "ceres/internal/eigen.h"
 #include "glog/logging.h"
 #include "gtest/gtest.h"
@@ -77,9 +78,8 @@
     int col;
     int row_stride;
     int col_stride;
-    CellInfo* cell =  m.GetCell(row_block_id, col_block_id,
-                                &row, &col,
-                                &row_stride, &col_stride);
+    CellInfo* cell = m.GetCell(
+        row_block_id, col_block_id, &row, &col, &row_stride, &col_stride);
     EXPECT_TRUE(cell != NULL);
     EXPECT_EQ(row, 0);
     EXPECT_EQ(col, 0);
@@ -87,9 +87,9 @@
     EXPECT_EQ(col_stride, blocks[col_block_id]);
 
     // Write into the block
-    MatrixRef(cell->values, row_stride, col_stride).block(
-        row, col, blocks[row_block_id], blocks[col_block_id]) =
-        (row_block_id + 1) * (col_block_id +1) *
+    MatrixRef(cell->values, row_stride, col_stride)
+        .block(row, col, blocks[row_block_id], blocks[col_block_id]) =
+        (row_block_id + 1) * (col_block_id + 1) *
         Matrix::Ones(blocks[row_block_id], blocks[col_block_id]);
   }
 
@@ -103,9 +103,8 @@
   double kTolerance = 1e-14;
 
   // (0, 0)
-  EXPECT_NEAR((dense.block(0, 0, 3, 3) - Matrix::Ones(3, 3)).norm(),
-              0.0,
-              kTolerance);
+  EXPECT_NEAR(
+      (dense.block(0, 0, 3, 3) - Matrix::Ones(3, 3)).norm(), 0.0, kTolerance);
   // (1, 1)
   EXPECT_NEAR((dense.block(3, 3, 4, 4) - 2 * 2 * Matrix::Ones(4, 4)).norm(),
               0.0,
@@ -120,8 +119,8 @@
               kTolerance);
 
   // There is nothing else in the matrix besides these four blocks.
-  EXPECT_NEAR(dense.norm(), sqrt(9. + 16. * 16. + 36. * 20. + 9. * 15.),
-              kTolerance);
+  EXPECT_NEAR(
+      dense.norm(), sqrt(9. + 16. * 16. + 36. * 20. + 9. * 15.), kTolerance);
 
   Vector x = Vector::Ones(dense.rows());
   Vector actual_y = Vector::Zero(dense.rows());
@@ -131,15 +130,14 @@
   m.SymmetricRightMultiply(x.data(), actual_y.data());
   EXPECT_NEAR((expected_y - actual_y).norm(), 0.0, kTolerance)
       << "actual: " << actual_y.transpose() << "\n"
-      << "expected: " << expected_y.transpose()
-      << "matrix: \n " << dense;
+      << "expected: " << expected_y.transpose() << "matrix: \n " << dense;
 }
 
 // IntPairToLong is private, thus this fixture is needed to access and
 // test it.
 class BlockRandomAccessSparseMatrixTest : public ::testing::Test {
  public:
-  virtual void SetUp() {
+  void SetUp() final {
     vector<int> blocks;
     blocks.push_back(1);
     set<pair<int, int>> block_pairs;
@@ -155,14 +153,13 @@
   }
 
   void CheckLongToIntPair() {
-    uint64_t max_rows =  m_->kMaxRowBlocks;
+    uint64_t max_rows = m_->kMaxRowBlocks;
     for (int row = max_rows - 10; row < max_rows; ++row) {
       for (int col = 0; col < 10; ++col) {
         int row_computed;
         int col_computed;
-        m_->LongToIntPair(m_->IntPairToLong(row, col),
-                          &row_computed,
-                          &col_computed);
+        m_->LongToIntPair(
+            m_->IntPairToLong(row, col), &row_computed, &col_computed);
         EXPECT_EQ(row, row_computed);
         EXPECT_EQ(col, col_computed);
       }
diff --git a/internal/ceres/block_sparse_matrix.cc b/internal/ceres/block_sparse_matrix.cc
index 8f50f35..5efd2e1 100644
--- a/internal/ceres/block_sparse_matrix.cc
+++ b/internal/ceres/block_sparse_matrix.cc
@@ -30,9 +30,10 @@
 
 #include "ceres/block_sparse_matrix.h"
 
-#include <cstddef>
 #include <algorithm>
+#include <cstddef>
 #include <vector>
+
 #include "ceres/block_structure.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/random.h"
@@ -77,8 +78,8 @@
   CHECK_GE(num_rows_, 0);
   CHECK_GE(num_cols_, 0);
   CHECK_GE(num_nonzeros_, 0);
-  VLOG(2) << "Allocating values array with "
-          << num_nonzeros_ * sizeof(double) << " bytes.";  // NOLINT
+  VLOG(2) << "Allocating values array with " << num_nonzeros_ * sizeof(double)
+          << " bytes.";  // NOLINT
   values_.reset(new double[num_nonzeros_]);
   max_num_nonzeros_ = num_nonzeros_;
   CHECK(values_ != nullptr);
@@ -88,7 +89,7 @@
   std::fill(values_.get(), values_.get() + num_nonzeros_, 0.0);
 }
 
-void BlockSparseMatrix::RightMultiply(const double* x,  double* y) const {
+void BlockSparseMatrix::RightMultiply(const double* x, double* y) const {
   CHECK(x != nullptr);
   CHECK(y != nullptr);
 
@@ -101,7 +102,9 @@
       int col_block_size = block_structure_->cols[col_block_id].size;
       int col_block_pos = block_structure_->cols[col_block_id].position;
       MatrixVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
-          values_.get() + cells[j].position, row_block_size, col_block_size,
+          values_.get() + cells[j].position,
+          row_block_size,
+          col_block_size,
           x + col_block_pos,
           y + row_block_pos);
     }
@@ -121,7 +124,9 @@
       int col_block_size = block_structure_->cols[col_block_id].size;
       int col_block_pos = block_structure_->cols[col_block_id].position;
       MatrixTransposeVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
-          values_.get() + cells[j].position, row_block_size, col_block_size,
+          values_.get() + cells[j].position,
+          row_block_size,
+          col_block_size,
           x + row_block_pos,
           y + col_block_pos);
     }
@@ -138,8 +143,8 @@
       int col_block_id = cells[j].block_id;
       int col_block_size = block_structure_->cols[col_block_id].size;
       int col_block_pos = block_structure_->cols[col_block_id].position;
-      const MatrixRef m(values_.get() + cells[j].position,
-                        row_block_size, col_block_size);
+      const MatrixRef m(
+          values_.get() + cells[j].position, row_block_size, col_block_size);
       VectorRef(x + col_block_pos, col_block_size) += m.colwise().squaredNorm();
     }
   }
@@ -155,8 +160,8 @@
       int col_block_id = cells[j].block_id;
       int col_block_size = block_structure_->cols[col_block_id].size;
       int col_block_pos = block_structure_->cols[col_block_id].position;
-      MatrixRef m(values_.get() + cells[j].position,
-                        row_block_size, col_block_size);
+      MatrixRef m(
+          values_.get() + cells[j].position, row_block_size, col_block_size);
       m *= ConstVectorRef(scale + col_block_pos, col_block_size).asDiagonal();
     }
   }
@@ -178,8 +183,8 @@
       int col_block_size = block_structure_->cols[col_block_id].size;
       int col_block_pos = block_structure_->cols[col_block_id].position;
       int jac_pos = cells[j].position;
-      m.block(row_block_pos, col_block_pos, row_block_size, col_block_size)
-          += MatrixRef(values_.get() + jac_pos, row_block_size, col_block_size);
+      m.block(row_block_pos, col_block_pos, row_block_size, col_block_size) +=
+          MatrixRef(values_.get() + jac_pos, row_block_size, col_block_size);
     }
   }
 }
@@ -201,7 +206,7 @@
       int col_block_size = block_structure_->cols[col_block_id].size;
       int col_block_pos = block_structure_->cols[col_block_id].position;
       int jac_pos = cells[j].position;
-       for (int r = 0; r < row_block_size; ++r) {
+      for (int r = 0; r < row_block_size; ++r) {
         for (int c = 0; c < col_block_size; ++c, ++jac_pos) {
           matrix->mutable_rows()[jac_pos] = row_block_pos + r;
           matrix->mutable_cols()[jac_pos] = col_block_pos + c;
@@ -215,8 +220,7 @@
 
 // Return a pointer to the block structure. We continue to hold
 // ownership of the object though.
-const CompressedRowBlockStructure* BlockSparseMatrix::block_structure()
-    const {
+const CompressedRowBlockStructure* BlockSparseMatrix::block_structure() const {
   return block_structure_.get();
 }
 
@@ -233,7 +237,8 @@
       int jac_pos = cells[j].position;
       for (int r = 0; r < row_block_size; ++r) {
         for (int c = 0; c < col_block_size; ++c) {
-          fprintf(file, "% 10d % 10d %17f\n",
+          fprintf(file,
+                  "% 10d % 10d %17f\n",
                   row_block_pos + r,
                   col_block_pos + c,
                   values_[jac_pos++]);
@@ -369,7 +374,6 @@
     int row_block_position = 0;
     int value_position = 0;
     for (int r = 0; r < options.num_row_blocks; ++r) {
-
       const int delta_block_size =
           Uniform(options.max_row_block_size - options.min_row_block_size);
       const int row_block_size = options.min_row_block_size + delta_block_size;
diff --git a/internal/ceres/block_sparse_matrix.h b/internal/ceres/block_sparse_matrix.h
index 366ef87..e5b3634 100644
--- a/internal/ceres/block_sparse_matrix.h
+++ b/internal/ceres/block_sparse_matrix.h
@@ -35,9 +35,11 @@
 #define CERES_INTERNAL_BLOCK_SPARSE_MATRIX_H_
 
 #include <memory>
+
 #include "ceres/block_structure.h"
-#include "ceres/sparse_matrix.h"
 #include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
+#include "ceres/sparse_matrix.h"
 
 namespace ceres {
 namespace internal {
@@ -52,7 +54,7 @@
 //
 //   internal/ceres/block_structure.h
 //
-class BlockSparseMatrix : public SparseMatrix {
+class CERES_EXPORT_INTERNAL BlockSparseMatrix : public SparseMatrix {
  public:
   // Construct a block sparse matrix with a fully initialized
   // CompressedRowBlockStructure objected. The matrix takes over
@@ -69,19 +71,21 @@
   virtual ~BlockSparseMatrix();
 
   // Implementation of SparseMatrix interface.
-  virtual void SetZero();
-  virtual void RightMultiply(const double* x, double* y) const;
-  virtual void LeftMultiply(const double* x, double* y) const;
-  virtual void SquaredColumnNorm(double* x) const;
-  virtual void ScaleColumns(const double* scale);
-  virtual void ToDenseMatrix(Matrix* dense_matrix) const;
-  virtual void ToTextFile(FILE* file) const;
+  void SetZero() final;
+  void RightMultiply(const double* x, double* y) const final;
+  void LeftMultiply(const double* x, double* y) const final;
+  void SquaredColumnNorm(double* x) const final;
+  void ScaleColumns(const double* scale) final;
+  void ToDenseMatrix(Matrix* dense_matrix) const final;
+  void ToTextFile(FILE* file) const final;
 
-  virtual int num_rows()         const { return num_rows_;     }
-  virtual int num_cols()         const { return num_cols_;     }
-  virtual int num_nonzeros()     const { return num_nonzeros_; }
-  virtual const double* values() const { return values_.get(); }
-  virtual double* mutable_values()     { return values_.get(); }
+  // clang-format off
+  int num_rows()         const final { return num_rows_;     }
+  int num_cols()         const final { return num_cols_;     }
+  int num_nonzeros()     const final { return num_nonzeros_; }
+  const double* values() const final { return values_.get(); }
+  double* mutable_values()     final { return values_.get(); }
+  // clang-format on
 
   void ToTripletSparseMatrix(TripletSparseMatrix* matrix) const;
   const CompressedRowBlockStructure* block_structure() const;
@@ -94,8 +98,7 @@
   void DeleteRowBlocks(int delta_row_blocks);
 
   static BlockSparseMatrix* CreateDiagonalMatrix(
-      const double* diagonal,
-      const std::vector<Block>& column_blocks);
+      const double* diagonal, const std::vector<Block>& column_blocks);
 
   struct RandomMatrixOptions {
     int num_row_blocks = 0;
@@ -133,6 +136,31 @@
   std::unique_ptr<CompressedRowBlockStructure> block_structure_;
 };
 
+// A number of algorithms like the SchurEliminator do not need
+// access to the full BlockSparseMatrix interface. They only
+// need read only access to the values array and the block structure.
+//
+// BlockSparseDataMatrix a struct that carries these two bits of
+// information
+class BlockSparseMatrixData {
+ public:
+  BlockSparseMatrixData(const BlockSparseMatrix& m)
+      : block_structure_(m.block_structure()), values_(m.values()){};
+
+  BlockSparseMatrixData(const CompressedRowBlockStructure* block_structure,
+                        const double* values)
+      : block_structure_(block_structure), values_(values) {}
+
+  const CompressedRowBlockStructure* block_structure() const {
+    return block_structure_;
+  }
+  const double* values() const { return values_; }
+
+ private:
+  const CompressedRowBlockStructure* block_structure_;
+  const double* values_;
+};
+
 }  // namespace internal
 }  // namespace ceres
 
diff --git a/internal/ceres/block_sparse_matrix_test.cc b/internal/ceres/block_sparse_matrix_test.cc
index 26fa9a2..02d3fb1 100644
--- a/internal/ceres/block_sparse_matrix_test.cc
+++ b/internal/ceres/block_sparse_matrix_test.cc
@@ -32,6 +32,7 @@
 
 #include <memory>
 #include <string>
+
 #include "ceres/casts.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_least_squares_problems.h"
@@ -43,8 +44,8 @@
 namespace internal {
 
 class BlockSparseMatrixTest : public ::testing::Test {
- protected :
-  virtual void SetUp() {
+ protected:
+  void SetUp() final {
     std::unique_ptr<LinearLeastSquaresProblem> problem(
         CreateLinearLeastSquaresProblemFromId(2));
     CHECK(problem != nullptr);
@@ -159,13 +160,13 @@
 
     A_->RightMultiply(x.data(), y_a.data());
     B_->RightMultiply(x.data(), y_b.data());
-    EXPECT_LT((y_a.head(B_->num_rows()) - y_b.head(B_->num_rows())).norm(), 1e-12);
+    EXPECT_LT((y_a.head(B_->num_rows()) - y_b.head(B_->num_rows())).norm(),
+              1e-12);
     Vector expected_tail = Vector::Zero(A_->num_cols());
     expected_tail(i) = diagonal(i);
     EXPECT_LT((y_a.tail(A_->num_cols()) - expected_tail).norm(), 1e-12);
   }
 
-
   A_->DeleteRowBlocks(column_blocks.size());
   EXPECT_EQ(A_->num_rows(), B_->num_rows());
   EXPECT_EQ(A_->num_cols(), B_->num_cols());
@@ -213,6 +214,5 @@
   }
 }
 
-
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/block_structure.cc b/internal/ceres/block_structure.cc
index 6479b60..39ba082 100644
--- a/internal/ceres/block_structure.cc
+++ b/internal/ceres/block_structure.cc
@@ -35,7 +35,7 @@
 
 bool CellLessThan(const Cell& lhs, const Cell& rhs) {
   if (lhs.block_id == rhs.block_id) {
-    return (lhs.position  < rhs.position);
+    return (lhs.position < rhs.position);
   }
   return (lhs.block_id < rhs.block_id);
 }
diff --git a/internal/ceres/block_structure.h b/internal/ceres/block_structure.h
index b5218c0..d49d7d3 100644
--- a/internal/ceres/block_structure.h
+++ b/internal/ceres/block_structure.h
@@ -40,6 +40,7 @@
 
 #include <cstdint>
 #include <vector>
+
 #include "ceres/internal/port.h"
 
 namespace ceres {
diff --git a/internal/ceres/bundle_adjustment_test_util.h b/internal/ceres/bundle_adjustment_test_util.h
index 7e076eb..074931f 100644
--- a/internal/ceres/bundle_adjustment_test_util.h
+++ b/internal/ceres/bundle_adjustment_test_util.h
@@ -37,9 +37,8 @@
 #include <cstdlib>
 #include <string>
 
-#include "ceres/internal/port.h"
-
 #include "ceres/autodiff_cost_function.h"
+#include "ceres/internal/port.h"
 #include "ceres/ordered_groups.h"
 #include "ceres/problem.h"
 #include "ceres/rotation.h"
@@ -73,29 +72,31 @@
   }
 
   ~BundleAdjustmentProblem() {
-    delete []point_index_;
-    delete []camera_index_;
-    delete []observations_;
-    delete []parameters_;
+    delete[] point_index_;
+    delete[] camera_index_;
+    delete[] observations_;
+    delete[] parameters_;
   }
 
   Problem* mutable_problem() { return &problem_; }
   Solver::Options* mutable_solver_options() { return &options_; }
 
-  int num_cameras()            const { return num_cameras_;        }
-  int num_points()             const { return num_points_;         }
-  int num_observations()       const { return num_observations_;   }
-  const int* point_index()     const { return point_index_;  }
+  // clang-format off
+  int num_cameras()            const { return num_cameras_; }
+  int num_points()             const { return num_points_; }
+  int num_observations()       const { return num_observations_; }
+  const int* point_index()     const { return point_index_; }
   const int* camera_index()    const { return camera_index_; }
   const double* observations() const { return observations_; }
-  double* mutable_cameras() { return parameters_; }
-  double* mutable_points() { return parameters_  + 9 * num_cameras_; }
+  double* mutable_cameras()          { return parameters_; }
+  double* mutable_points()           { return parameters_ + 9 * num_cameras_; }
+  // clang-format on
 
   static double kResidualTolerance;
 
  private:
   void ReadData(const string& filename) {
-    FILE * fptr = fopen(filename.c_str(), "r");
+    FILE* fptr = fopen(filename.c_str(), "r");
 
     if (!fptr) {
       LOG(FATAL) << "File Error: unable to open file " << filename;
@@ -106,9 +107,8 @@
     FscanfOrDie(fptr, "%d", &num_points_);
     FscanfOrDie(fptr, "%d", &num_observations_);
 
-    VLOG(1) << "Header: " << num_cameras_
-            << " " << num_points_
-            << " " << num_observations_;
+    VLOG(1) << "Header: " << num_cameras_ << " " << num_points_ << " "
+            << num_observations_;
 
     point_index_ = new int[num_observations_];
     camera_index_ = new int[num_observations_];
@@ -121,7 +121,7 @@
       FscanfOrDie(fptr, "%d", camera_index_ + i);
       FscanfOrDie(fptr, "%d", point_index_ + i);
       for (int j = 0; j < 2; ++j) {
-        FscanfOrDie(fptr, "%lf", observations_ + 2*i + j);
+        FscanfOrDie(fptr, "%lf", observations_ + 2 * i + j);
       }
     }
 
@@ -141,8 +141,8 @@
       // outputs a 2 dimensional residual.
       CostFunction* cost_function =
           new AutoDiffCostFunction<BundlerResidual, 2, 9, 3>(
-              new BundlerResidual(observations_[2*i + 0],
-                                  observations_[2*i + 1]));
+              new BundlerResidual(observations_[2 * i + 0],
+                                  observations_[2 * i + 1]));
 
       // Each observation corresponds to a pair of a camera and a point
       // which are identified by camera_index()[i] and
@@ -170,8 +170,8 @@
     options_.parameter_tolerance = 1e-10;
   }
 
-  template<typename T>
-  void FscanfOrDie(FILE *fptr, const char *format, T *value) {
+  template <typename T>
+  void FscanfOrDie(FILE* fptr, const char* format, T* value) {
     int num_scanned = fscanf(fptr, format, value);
     if (num_scanned != 1) {
       LOG(FATAL) << "Invalid UW data file.";
@@ -186,7 +186,7 @@
   struct BundlerResidual {
     // (u, v): the position of the observation with respect to the image
     // center point.
-    BundlerResidual(double u, double v): u(u), v(v) {}
+    BundlerResidual(double u, double v) : u(u), v(v) {}
 
     template <typename T>
     bool operator()(const T* const camera,
@@ -207,12 +207,12 @@
       // Compute the center of distortion.  The sign change comes from
       // the camera model that Noah Snavely's Bundler assumes, whereby
       // the camera coordinate system has a negative z axis.
-      T xp = - focal * p[0] / p[2];
-      T yp = - focal * p[1] / p[2];
+      T xp = -focal * p[0] / p[2];
+      T yp = -focal * p[1] / p[2];
 
       // Apply second and fourth order radial distortion.
-      T r2 = xp*xp + yp*yp;
-      T distortion = T(1.0) + r2  * (l1 + l2  * r2);
+      T r2 = xp * xp + yp * yp;
+      T distortion = T(1.0) + r2 * (l1 + l2 * r2);
 
       residuals[0] = distortion * xp - u;
       residuals[1] = distortion * yp - v;
diff --git a/internal/ceres/c_api.cc b/internal/ceres/c_api.cc
index ada8f3e..251cde4 100644
--- a/internal/ceres/c_api.cc
+++ b/internal/ceres/c_api.cc
@@ -34,9 +34,10 @@
 
 #include "ceres/c_api.h"
 
-#include <vector>
 #include <iostream>
 #include <string>
+#include <vector>
+
 #include "ceres/cost_function.h"
 #include "ceres/loss_function.h"
 #include "ceres/problem.h"
@@ -70,8 +71,7 @@
                        int num_residuals,
                        int num_parameter_blocks,
                        int* parameter_block_sizes)
-      : cost_function_(cost_function),
-        user_data_(user_data) {
+      : cost_function_(cost_function), user_data_(user_data) {
     set_num_residuals(num_residuals);
     for (int i = 0; i < num_parameter_blocks; ++i) {
       mutable_parameter_block_sizes()->push_back(parameter_block_sizes[i]);
@@ -80,13 +80,11 @@
 
   virtual ~CallbackCostFunction() {}
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
-    return (*cost_function_)(user_data_,
-                             const_cast<double**>(parameters),
-                             residuals,
-                             jacobians);
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
+    return (*cost_function_)(
+        user_data_, const_cast<double**>(parameters), residuals, jacobians);
   }
 
  private:
@@ -100,8 +98,8 @@
  public:
   explicit CallbackLossFunction(ceres_loss_function_t loss_function,
                                 void* user_data)
-    : loss_function_(loss_function), user_data_(user_data) {}
-  virtual void Evaluate(double sq_norm, double* rho) const {
+      : loss_function_(loss_function), user_data_(user_data) {}
+  void Evaluate(double sq_norm, double* rho) const final {
     (*loss_function_)(user_data_, sq_norm, rho);
   }
 
@@ -134,8 +132,8 @@
 void ceres_stock_loss_function(void* user_data,
                                double squared_norm,
                                double out[3]) {
-  reinterpret_cast<ceres::LossFunction*>(user_data)
-      ->Evaluate(squared_norm, out);
+  reinterpret_cast<ceres::LossFunction*>(user_data)->Evaluate(squared_norm,
+                                                              out);
 }
 
 ceres_residual_block_id_t* ceres_problem_add_residual_block(
@@ -159,16 +157,15 @@
 
   ceres::LossFunction* callback_loss_function = NULL;
   if (loss_function != NULL) {
-    callback_loss_function = new CallbackLossFunction(loss_function,
-                                                      loss_function_data);
+    callback_loss_function =
+        new CallbackLossFunction(loss_function, loss_function_data);
   }
 
   std::vector<double*> parameter_blocks(parameters,
                                         parameters + num_parameter_blocks);
   return reinterpret_cast<ceres_residual_block_id_t*>(
-      ceres_problem->AddResidualBlock(callback_cost_function,
-                                      callback_loss_function,
-                                      parameter_blocks));
+      ceres_problem->AddResidualBlock(
+          callback_cost_function, callback_loss_function, parameter_blocks));
 }
 
 void ceres_solve(ceres_problem_t* c_problem) {
diff --git a/internal/ceres/c_api_test.cc b/internal/ceres/c_api_test.cc
index 95b727a..043f6ab 100644
--- a/internal/ceres/c_api_test.cc
+++ b/internal/ceres/c_api_test.cc
@@ -37,6 +37,7 @@
 
 // Duplicated from curve_fitting.cc.
 int num_observations = 67;
+// clang-format off
 double data[] = {
   0.000000e+00, 1.133898e+00,
   7.500000e-02, 1.334902e+00,
@@ -106,13 +107,14 @@
   4.875000e+00, 4.727863e+00,
   4.950000e+00, 4.669206e+00,
 };
+// clang-format on
 
 // A test cost function, similar to the one in curve_fitting.c.
-int exponential_residual(void* user_data,
-                         double** parameters,
-                         double* residuals,
-                         double** jacobians) {
-  double* measurement = (double*) user_data;
+static int exponential_residual(void* user_data,
+                                double** parameters,
+                                double* residuals,
+                                double** jacobians) {
+  double* measurement = (double*)user_data;
   double x = measurement[0];
   double y = measurement[1];
   double m = parameters[0][0];
@@ -123,10 +125,10 @@
     return 1;
   }
   if (jacobians[0] != NULL) {
-    jacobians[0][0] = - x * exp(m * x + c);  // dr/dm
+    jacobians[0][0] = -x * exp(m * x + c);  // dr/dm
   }
   if (jacobians[1] != NULL) {
-    jacobians[1][0] =     - exp(m * x + c);  // dr/dc
+    jacobians[1][0] = -exp(m * x + c);  // dr/dc
   }
   return 1;
 }
@@ -137,8 +139,8 @@
 TEST(C_API, SimpleEndToEndTest) {
   double m = 0.0;
   double c = 0.0;
-  double *parameter_pointers[] = { &m, &c };
-  int parameter_sizes[] = { 1, 1 };
+  double* parameter_pointers[] = {&m, &c};
+  int parameter_sizes[] = {1, 1};
 
   ceres_problem_t* problem = ceres_create_problem();
   for (int i = 0; i < num_observations; ++i) {
@@ -162,16 +164,14 @@
   ceres_free_problem(problem);
 }
 
-template<typename T>
+template <typename T>
 class ScopedSetValue {
  public:
   ScopedSetValue(T* variable, T new_value)
       : variable_(variable), old_value_(*variable) {
     *variable = new_value;
   }
-  ~ScopedSetValue() {
-    *variable_ = old_value_;
-  }
+  ~ScopedSetValue() { *variable_ = old_value_; }
 
  private:
   T* variable_;
@@ -181,8 +181,8 @@
 TEST(C_API, LossFunctions) {
   double m = 0.2;
   double c = 0.03;
-  double *parameter_pointers[] = { &m, &c };
-  int parameter_sizes[] = { 1, 1 };
+  double* parameter_pointers[] = {&m, &c};
+  int parameter_sizes[] = {1, 1};
 
   // Create two outliers, but be careful to leave the data intact.
   ScopedSetValue<double> outlier1x(&data[12], 2.5);
@@ -191,19 +191,18 @@
   ScopedSetValue<double> outlier2y(&data[15], 30e3);
 
   // Create a cauchy cost function, and reuse it many times.
-  void* cauchy_loss_data =
-      ceres_create_cauchy_loss_function_data(5.0);
+  void* cauchy_loss_data = ceres_create_cauchy_loss_function_data(5.0);
 
   ceres_problem_t* problem = ceres_create_problem();
   for (int i = 0; i < num_observations; ++i) {
     ceres_problem_add_residual_block(
         problem,
-        exponential_residual,  // Cost function
-        &data[2 * i],          // Points to the (x,y) measurement
-        ceres_stock_loss_function,
-        cauchy_loss_data,      // Loss function user data
-        1,                     // Number of residuals
-        2,                     // Number of parameter blocks
+        exponential_residual,       // Cost function
+        &data[2 * i],               // Points to the (x,y) measurement
+        ceres_stock_loss_function,  //
+        cauchy_loss_data,           // Loss function user data
+        1,                          // Number of residuals
+        2,                          // Number of parameter blocks
         parameter_sizes,
         parameter_pointers);
   }
diff --git a/internal/ceres/callbacks.cc b/internal/ceres/callbacks.cc
index 84576e4..0e0df9d 100644
--- a/internal/ceres/callbacks.cc
+++ b/internal/ceres/callbacks.cc
@@ -28,8 +28,10 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
-#include <iostream>  // NO LINT
 #include "ceres/callbacks.h"
+
+#include <iostream>  // NO LINT
+
 #include "ceres/program.h"
 #include "ceres/stringprintf.h"
 #include "glog/logging.h"
@@ -76,8 +78,7 @@
 
 LoggingCallback::LoggingCallback(const MinimizerType minimizer_type,
                                  const bool log_to_stdout)
-    : minimizer_type(minimizer_type),
-      log_to_stdout_(log_to_stdout) {}
+    : minimizer_type(minimizer_type), log_to_stdout_(log_to_stdout) {}
 
 LoggingCallback::~LoggingCallback() {}
 
@@ -99,11 +100,13 @@
                           summary.iteration_time_in_seconds,
                           summary.cumulative_time_in_seconds);
   } else if (minimizer_type == TRUST_REGION) {
+    // clang-format off
     if (summary.iteration == 0) {
       output = "iter      cost      cost_change  |gradient|   |step|    tr_ratio  tr_radius  ls_iter  iter_time  total_time\n";  // NOLINT
     }
     const char* kReportRowFormat =
         "% 4d % 8e   % 3.2e   % 3.2e  % 3.2e  % 3.2e % 3.2e     % 4d   % 3.2e   % 3.2e";  // NOLINT
+    // clang-format on
     output += StringPrintf(kReportRowFormat,
                            summary.iteration,
                            summary.cost,
diff --git a/internal/ceres/callbacks.h b/internal/ceres/callbacks.h
index 288d6ae..47112b8 100644
--- a/internal/ceres/callbacks.h
+++ b/internal/ceres/callbacks.h
@@ -32,8 +32,9 @@
 #define CERES_INTERNAL_CALLBACKS_H_
 
 #include <string>
-#include "ceres/iteration_callback.h"
+
 #include "ceres/internal/port.h"
+#include "ceres/iteration_callback.h"
 
 namespace ceres {
 namespace internal {
@@ -46,7 +47,8 @@
  public:
   StateUpdatingCallback(Program* program, double* parameters);
   virtual ~StateUpdatingCallback();
-  virtual CallbackReturnType operator()(const IterationSummary& summary);
+  CallbackReturnType operator()(const IterationSummary& summary) final;
+
  private:
   Program* program_;
   double* parameters_;
@@ -60,7 +62,8 @@
                                              const double* internal_parameters,
                                              double* user_parameters);
   virtual ~GradientProblemSolverStateUpdatingCallback();
-  virtual CallbackReturnType operator()(const IterationSummary& summary);
+  CallbackReturnType operator()(const IterationSummary& summary) final;
+
  private:
   int num_parameters_;
   const double* internal_parameters_;
@@ -73,7 +76,7 @@
  public:
   LoggingCallback(MinimizerType minimizer_type, bool log_to_stdout);
   virtual ~LoggingCallback();
-  virtual CallbackReturnType operator()(const IterationSummary& summary);
+  CallbackReturnType operator()(const IterationSummary& summary) final;
 
  private:
   const MinimizerType minimizer_type;
diff --git a/internal/ceres/canonical_views_clustering.cc b/internal/ceres/canonical_views_clustering.cc
index b2fd49f..c193735 100644
--- a/internal/ceres/canonical_views_clustering.cc
+++ b/internal/ceres/canonical_views_clustering.cc
@@ -31,8 +31,8 @@
 
 #include "ceres/canonical_views_clustering.h"
 
-#include <unordered_set>
 #include <unordered_map>
+#include <unordered_set>
 
 #include "ceres/graph.h"
 #include "ceres/map_util.h"
@@ -126,8 +126,7 @@
 
     // Add canonical view if quality improves, or if minimum is not
     // yet met, otherwise break.
-    if ((best_difference <= 0) &&
-        (centers->size() >= options_.min_views)) {
+    if ((best_difference <= 0) && (centers->size() >= options_.min_views)) {
       break;
     }
 
@@ -141,8 +140,7 @@
 
 // Return the set of vertices of the graph which have valid vertex
 // weights.
-void CanonicalViewsClustering::FindValidViews(
-    IntSet* valid_views) const {
+void CanonicalViewsClustering::FindValidViews(IntSet* valid_views) const {
   const IntSet& views = graph_->vertices();
   for (const auto& view : views) {
     if (graph_->VertexWeight(view) != WeightedGraph<int>::InvalidWeight()) {
@@ -154,8 +152,7 @@
 // Computes the difference in the quality score if 'candidate' were
 // added to the set of canonical views.
 double CanonicalViewsClustering::ComputeClusteringQualityDifference(
-    const int candidate,
-    const vector<int>& centers) const {
+    const int candidate, const vector<int>& centers) const {
   // View score.
   double difference =
       options_.view_score_weight * graph_->VertexWeight(candidate);
@@ -179,7 +176,7 @@
   // Orthogonality.
   for (int i = 0; i < centers.size(); ++i) {
     difference -= options_.similarity_penalty_weight *
-        graph_->EdgeWeight(centers[i], candidate);
+                  graph_->EdgeWeight(centers[i], candidate);
   }
 
   return difference;
@@ -192,8 +189,7 @@
   for (const auto& neighbor : neighbors) {
     const double old_similarity =
         FindWithDefault(view_to_canonical_view_similarity_, neighbor, 0.0);
-    const double new_similarity =
-        graph_->EdgeWeight(neighbor, canonical_view);
+    const double new_similarity = graph_->EdgeWeight(neighbor, canonical_view);
     if (new_similarity > old_similarity) {
       view_to_canonical_view_[neighbor] = canonical_view;
       view_to_canonical_view_similarity_[neighbor] = new_similarity;
@@ -203,8 +199,7 @@
 
 // Assign a cluster id to each view.
 void CanonicalViewsClustering::ComputeClusterMembership(
-    const vector<int>& centers,
-    IntMap* membership) const {
+    const vector<int>& centers, IntMap* membership) const {
   CHECK(membership != nullptr);
   membership->clear();
 
@@ -214,7 +209,7 @@
     center_to_cluster_id[centers[i]] = i;
   }
 
-  static const int kInvalidClusterId = -1;
+  static constexpr int kInvalidClusterId = -1;
 
   const IntSet& views = graph_->vertices();
   for (const auto& view : views) {
diff --git a/internal/ceres/canonical_views_clustering.h b/internal/ceres/canonical_views_clustering.h
index 630adfe..465233d 100644
--- a/internal/ceres/canonical_views_clustering.h
+++ b/internal/ceres/canonical_views_clustering.h
@@ -45,6 +45,7 @@
 #include <vector>
 
 #include "ceres/graph.h"
+#include "ceres/internal/port.h"
 
 namespace ceres {
 namespace internal {
@@ -94,13 +95,13 @@
 // It is possible depending on the configuration of the clustering
 // algorithm that some of the vertices may not be assigned to any
 // cluster. In this case they are assigned to a cluster with id = -1;
-void ComputeCanonicalViewsClustering(
+CERES_EXPORT_INTERNAL void ComputeCanonicalViewsClustering(
     const CanonicalViewsClusteringOptions& options,
     const WeightedGraph<int>& graph,
     std::vector<int>* centers,
     std::unordered_map<int, int>* membership);
 
-struct CanonicalViewsClusteringOptions {
+struct CERES_EXPORT_INTERNAL CanonicalViewsClusteringOptions {
   // The minimum number of canonical views to compute.
   int min_views = 3;
 
diff --git a/internal/ceres/canonical_views_clustering_test.cc b/internal/ceres/canonical_views_clustering_test.cc
index a8db293..0593d65 100644
--- a/internal/ceres/canonical_views_clustering_test.cc
+++ b/internal/ceres/canonical_views_clustering_test.cc
@@ -32,6 +32,7 @@
 #include "ceres/canonical_views_clustering.h"
 
 #include <unordered_map>
+
 #include "ceres/graph.h"
 #include "gtest/gtest.h"
 
@@ -41,7 +42,7 @@
 const int kVertexIds[] = {0, 1, 2, 3};
 class CanonicalViewsTest : public ::testing::Test {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     // The graph structure is as follows.
     //
     // Vertex weights:   0      2      2      0
@@ -110,7 +111,6 @@
   EXPECT_EQ(centers_[0], kVertexIds[1]);
 }
 
-
 // Increases view score weight so vertex 2 will be chosen.
 TEST_F(CanonicalViewsTest, ViewScoreTest) {
   options_.min_views = 0;
diff --git a/internal/ceres/casts.h b/internal/ceres/casts.h
index f18fdea..d137071 100644
--- a/internal/ceres/casts.h
+++ b/internal/ceres/casts.h
@@ -56,15 +56,15 @@
 //
 // base::identity_ is used to make a non-deduced context, which
 // forces all callers to explicitly specify the template argument.
-template<typename To>
+template <typename To>
 inline To implicit_cast(typename identity_<To>::type to) {
   return to;
 }
 
 // This version of implicit_cast is used when two template arguments
 // are specified. It's obsolete and should not be used.
-template<typename To, typename From>
-inline To implicit_cast(typename identity_<From>::type const &f) {
+template <typename To, typename From>
+inline To implicit_cast(typename identity_<From>::type const& f) {
   return f;
 }
 
@@ -86,8 +86,8 @@
 //    if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);
 // You should design the code some other way not to need this.
 
-template<typename To, typename From>     // use like this: down_cast<T*>(foo);
-inline To down_cast(From* f) {                   // so we only accept pointers
+template <typename To, typename From>  // use like this: down_cast<T*>(foo);
+inline To down_cast(From* f) {         // so we only accept pointers
   // Ensures that To is a sub-type of From *.  This test is here only
   // for compile-time type checking, and has no overhead in an
   // optimized build at run-time, as it will be optimized away
diff --git a/internal/ceres/cgnr_linear_operator.h b/internal/ceres/cgnr_linear_operator.h
index ad0c627..beb8bbc 100644
--- a/internal/ceres/cgnr_linear_operator.h
+++ b/internal/ceres/cgnr_linear_operator.h
@@ -33,8 +33,9 @@
 
 #include <algorithm>
 #include <memory>
-#include "ceres/linear_operator.h"
+
 #include "ceres/internal/eigen.h"
+#include "ceres/linear_operator.h"
 
 namespace ceres {
 namespace internal {
@@ -79,12 +80,11 @@
 // Note: This class is not thread safe, since it uses some temporary storage.
 class CgnrLinearOperator : public LinearOperator {
  public:
-  CgnrLinearOperator(const LinearOperator& A, const double *D)
-      : A_(A), D_(D), z_(new double[A.num_rows()]) {
-  }
+  CgnrLinearOperator(const LinearOperator& A, const double* D)
+      : A_(A), D_(D), z_(new double[A.num_rows()]) {}
   virtual ~CgnrLinearOperator() {}
 
-  virtual void RightMultiply(const double* x, double* y) const {
+  void RightMultiply(const double* x, double* y) const final {
     std::fill(z_.get(), z_.get() + A_.num_rows(), 0.0);
 
     // z = Ax
@@ -96,17 +96,17 @@
     // y = y + DtDx
     if (D_ != NULL) {
       int n = A_.num_cols();
-      VectorRef(y, n).array() += ConstVectorRef(D_, n).array().square() *
-                                 ConstVectorRef(x, n).array();
+      VectorRef(y, n).array() +=
+          ConstVectorRef(D_, n).array().square() * ConstVectorRef(x, n).array();
     }
   }
 
-  virtual void LeftMultiply(const double* x, double* y) const {
+  void LeftMultiply(const double* x, double* y) const final {
     RightMultiply(x, y);
   }
 
-  virtual int num_rows() const { return A_.num_cols(); }
-  virtual int num_cols() const { return A_.num_cols(); }
+  int num_rows() const final { return A_.num_cols(); }
+  int num_cols() const final { return A_.num_cols(); }
 
  private:
   const LinearOperator& A_;
diff --git a/internal/ceres/cgnr_solver.cc b/internal/ceres/cgnr_solver.cc
index 463fbbd..9dba1cf 100644
--- a/internal/ceres/cgnr_solver.cc
+++ b/internal/ceres/cgnr_solver.cc
@@ -35,6 +35,7 @@
 #include "ceres/conjugate_gradients_solver.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_solver.h"
+#include "ceres/subset_preconditioner.h"
 #include "ceres/wall_time.h"
 #include "glog/logging.h"
 
@@ -42,10 +43,14 @@
 namespace internal {
 
 CgnrSolver::CgnrSolver(const LinearSolver::Options& options)
-  : options_(options) {
+    : options_(options) {
   if (options_.preconditioner_type != JACOBI &&
-      options_.preconditioner_type != IDENTITY) {
-    LOG(FATAL) << "CGNR only supports IDENTITY and JACOBI preconditioners.";
+      options_.preconditioner_type != IDENTITY &&
+      options_.preconditioner_type != SUBSET) {
+    LOG(FATAL)
+        << "Preconditioner = "
+        << PreconditionerTypeToString(options_.preconditioner_type) << ". "
+        << "Congratulations, you found a bug in Ceres. Please report it.";
   }
 }
 
@@ -63,16 +68,31 @@
   z.setZero();
   A->LeftMultiply(b, z.data());
 
-  // Precondition if necessary.
-  LinearSolver::PerSolveOptions cg_per_solve_options = per_solve_options;
-  if (options_.preconditioner_type == JACOBI) {
-    if (preconditioner_.get() == NULL) {
+  if (!preconditioner_) {
+    if (options_.preconditioner_type == JACOBI) {
       preconditioner_.reset(new BlockJacobiPreconditioner(*A));
+    } else if (options_.preconditioner_type == SUBSET) {
+      Preconditioner::Options preconditioner_options;
+      preconditioner_options.type = SUBSET;
+      preconditioner_options.subset_preconditioner_start_row_block =
+          options_.subset_preconditioner_start_row_block;
+      preconditioner_options.sparse_linear_algebra_library_type =
+          options_.sparse_linear_algebra_library_type;
+      preconditioner_options.use_postordering = options_.use_postordering;
+      preconditioner_options.num_threads = options_.num_threads;
+      preconditioner_options.context = options_.context;
+      preconditioner_.reset(
+          new SubsetPreconditioner(preconditioner_options, *A));
     }
-    preconditioner_->Update(*A, per_solve_options.D);
-    cg_per_solve_options.preconditioner = preconditioner_.get();
   }
 
+  if (preconditioner_) {
+    preconditioner_->Update(*A, per_solve_options.D);
+  }
+
+  LinearSolver::PerSolveOptions cg_per_solve_options = per_solve_options;
+  cg_per_solve_options.preconditioner = preconditioner_.get();
+
   // Solve (AtA + DtD)x = z (= Atb).
   VectorRef(x, A->num_cols()).setZero();
   CgnrLinearOperator lhs(*A, per_solve_options.D);
diff --git a/internal/ceres/cgnr_solver.h b/internal/ceres/cgnr_solver.h
index 0bd1883..bc701c0 100644
--- a/internal/ceres/cgnr_solver.h
+++ b/internal/ceres/cgnr_solver.h
@@ -32,6 +32,7 @@
 #define CERES_INTERNAL_CGNR_SOLVER_H_
 
 #include <memory>
+
 #include "ceres/linear_solver.h"
 
 namespace ceres {
@@ -55,11 +56,10 @@
   void operator=(const CgnrSolver&) = delete;
   virtual ~CgnrSolver();
 
-  virtual Summary SolveImpl(
-      BlockSparseMatrix* A,
-      const double* b,
-      const LinearSolver::PerSolveOptions& per_solve_options,
-      double* x);
+  Summary SolveImpl(BlockSparseMatrix* A,
+                    const double* b,
+                    const LinearSolver::PerSolveOptions& per_solve_options,
+                    double* x) final;
 
  private:
   const LinearSolver::Options options_;
diff --git a/internal/ceres/compressed_col_sparse_matrix_utils.cc b/internal/ceres/compressed_col_sparse_matrix_utils.cc
index 3f6672f..e1f6bb8 100644
--- a/internal/ceres/compressed_col_sparse_matrix_utils.cc
+++ b/internal/ceres/compressed_col_sparse_matrix_utils.cc
@@ -30,8 +30,9 @@
 
 #include "ceres/compressed_col_sparse_matrix_utils.h"
 
-#include <vector>
 #include <algorithm>
+#include <vector>
+
 #include "ceres/internal/port.h"
 #include "glog/logging.h"
 
@@ -40,13 +41,12 @@
 
 using std::vector;
 
-void CompressedColumnScalarMatrixToBlockMatrix(
-    const int* scalar_rows,
-    const int* scalar_cols,
-    const vector<int>& row_blocks,
-    const vector<int>& col_blocks,
-    vector<int>* block_rows,
-    vector<int>* block_cols) {
+void CompressedColumnScalarMatrixToBlockMatrix(const int* scalar_rows,
+                                               const int* scalar_cols,
+                                               const vector<int>& row_blocks,
+                                               const vector<int>& col_blocks,
+                                               vector<int>* block_rows,
+                                               vector<int>* block_cols) {
   CHECK(block_rows != nullptr);
   CHECK(block_cols != nullptr);
   block_rows->clear();
@@ -71,10 +71,8 @@
   for (int col_block = 0; col_block < num_col_blocks; ++col_block) {
     int column_size = 0;
     for (int idx = scalar_cols[c]; idx < scalar_cols[c + 1]; ++idx) {
-      vector<int>::const_iterator it =
-          std::lower_bound(row_block_starts.begin(),
-                           row_block_starts.end(),
-                           scalar_rows[idx]);
+      vector<int>::const_iterator it = std::lower_bound(
+          row_block_starts.begin(), row_block_starts.end(), scalar_rows[idx]);
       // Since we are using lower_bound, it will return the row id
       // where the row block starts. For everything but the first row
       // of the block, where these values will be the same, we can
@@ -104,7 +102,7 @@
 
   // block_starts = [0, block1, block1 + block2 ..]
   vector<int> block_starts(num_blocks);
-  for (int i = 0, cursor = 0; i < num_blocks ; ++i) {
+  for (int i = 0, cursor = 0; i < num_blocks; ++i) {
     block_starts[i] = cursor;
     cursor += blocks[i];
   }
diff --git a/internal/ceres/compressed_col_sparse_matrix_utils.h b/internal/ceres/compressed_col_sparse_matrix_utils.h
index da2109f..d442e1a 100644
--- a/internal/ceres/compressed_col_sparse_matrix_utils.h
+++ b/internal/ceres/compressed_col_sparse_matrix_utils.h
@@ -32,6 +32,7 @@
 #define CERES_INTERNAL_COMPRESSED_COL_SPARSE_MATRIX_UTILS_H_
 
 #include <vector>
+
 #include "ceres/internal/port.h"
 
 namespace ceres {
@@ -47,7 +48,7 @@
 // and column block j, then it is expected that A contains at least
 // one non-zero entry corresponding to the top left entry of c_ij,
 // as that entry is used to detect the presence of a non-zero c_ij.
-void CompressedColumnScalarMatrixToBlockMatrix(
+CERES_EXPORT_INTERNAL void CompressedColumnScalarMatrixToBlockMatrix(
     const int* scalar_rows,
     const int* scalar_cols,
     const std::vector<int>& row_blocks,
@@ -58,7 +59,7 @@
 // Given a set of blocks and a permutation of these blocks, compute
 // the corresponding "scalar" ordering, where the scalar ordering of
 // size sum(blocks).
-void BlockOrderingToScalarOrdering(
+CERES_EXPORT_INTERNAL void BlockOrderingToScalarOrdering(
     const std::vector<int>& blocks,
     const std::vector<int>& block_ordering,
     std::vector<int>* scalar_ordering);
@@ -101,7 +102,7 @@
       const double v = values[idx];
       rhs_and_solution[c] -= v * rhs_and_solution[r];
     }
-    rhs_and_solution[c] =  rhs_and_solution[c] / values[cols[c + 1] - 1];
+    rhs_and_solution[c] = rhs_and_solution[c] / values[cols[c + 1] - 1];
   }
 }
 
@@ -132,7 +133,7 @@
       const double v = values[idx];
       solution[c] -= v * solution[r];
     }
-    solution[c] =  solution[c] / values[cols[c + 1] - 1];
+    solution[c] = solution[c] / values[cols[c + 1] - 1];
   }
 
   SolveUpperTriangularInPlace(num_cols, rows, cols, values, solution);
diff --git a/internal/ceres/compressed_col_sparse_matrix_utils_test.cc b/internal/ceres/compressed_col_sparse_matrix_utils_test.cc
index 2162b9f..339c064 100644
--- a/internal/ceres/compressed_col_sparse_matrix_utils_test.cc
+++ b/internal/ceres/compressed_col_sparse_matrix_utils_test.cc
@@ -28,15 +28,16 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/compressed_col_sparse_matrix_utils.h"
 
 #include <algorithm>
 #include <numeric>
-#include "ceres/compressed_col_sparse_matrix_utils.h"
+
+#include "Eigen/SparseCore"
 #include "ceres/internal/port.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "glog/logging.h"
 #include "gtest/gtest.h"
-#include "Eigen/SparseCore"
 
 namespace ceres {
 namespace internal {
@@ -78,25 +79,26 @@
   expected_scalar_ordering.push_back(8);
 
   vector<int> scalar_ordering;
-  BlockOrderingToScalarOrdering(blocks,
-                                block_ordering,
-                                &scalar_ordering);
+  BlockOrderingToScalarOrdering(blocks, block_ordering, &scalar_ordering);
   EXPECT_EQ(scalar_ordering.size(), expected_scalar_ordering.size());
   for (int i = 0; i < expected_scalar_ordering.size(); ++i) {
     EXPECT_EQ(scalar_ordering[i], expected_scalar_ordering[i]);
   }
 }
 
-void FillBlock(const vector<int>& row_blocks,
-               const vector<int>& col_blocks,
-               const int row_block_id,
-               const int col_block_id,
-               vector<Eigen::Triplet<double>>* triplets) {
-  const int row_offset = std::accumulate(&row_blocks[0], &row_blocks[row_block_id], 0);
-  const int col_offset = std::accumulate(&col_blocks[0], &col_blocks[col_block_id], 0);
+static void FillBlock(const vector<int>& row_blocks,
+                      const vector<int>& col_blocks,
+                      const int row_block_id,
+                      const int col_block_id,
+                      vector<Eigen::Triplet<double>>* triplets) {
+  const int row_offset =
+      std::accumulate(&row_blocks[0], &row_blocks[row_block_id], 0);
+  const int col_offset =
+      std::accumulate(&col_blocks[0], &col_blocks[col_block_id], 0);
   for (int r = 0; r < row_blocks[row_block_id]; ++r) {
     for (int c = 0; c < col_blocks[col_block_id]; ++c) {
-      triplets->push_back(Eigen::Triplet<double>(row_offset + r, col_offset + c, 1.0));
+      triplets->push_back(
+          Eigen::Triplet<double>(row_offset + r, col_offset + c, 1.0));
     }
   }
 }
@@ -110,7 +112,6 @@
   // [2]  x x
   // num_nonzeros = 1 + 3 + 4 + 4 + 1 + 2 = 15
 
-
   vector<int> col_blocks;
   col_blocks.push_back(1);
   col_blocks.push_back(2);
@@ -122,8 +123,10 @@
   row_blocks.push_back(2);
   row_blocks.push_back(2);
 
-  const int num_rows = std::accumulate(row_blocks.begin(), row_blocks.end(), 0.0);
-  const int num_cols = std::accumulate(col_blocks.begin(), col_blocks.end(), 0.0);
+  const int num_rows =
+      std::accumulate(row_blocks.begin(), row_blocks.end(), 0.0);
+  const int num_cols =
+      std::accumulate(col_blocks.begin(), col_blocks.end(), 0.0);
 
   vector<Eigen::Triplet<double>> triplets;
   FillBlock(row_blocks, col_blocks, 0, 0, &triplets);
@@ -152,13 +155,12 @@
 
   vector<int> compressed_block_rows;
   vector<int> compressed_block_cols;
-  CompressedColumnScalarMatrixToBlockMatrix(
-      sparse_matrix.innerIndexPtr(),
-      sparse_matrix.outerIndexPtr(),
-      row_blocks,
-      col_blocks,
-      &compressed_block_rows,
-      &compressed_block_cols);
+  CompressedColumnScalarMatrixToBlockMatrix(sparse_matrix.innerIndexPtr(),
+                                            sparse_matrix.outerIndexPtr(),
+                                            row_blocks,
+                                            col_blocks,
+                                            &compressed_block_rows,
+                                            &compressed_block_cols);
 
   EXPECT_EQ(compressed_block_rows, expected_compressed_block_rows);
   EXPECT_EQ(compressed_block_cols, expected_compressed_block_cols);
@@ -203,13 +205,10 @@
 
 TEST_F(SolveUpperTriangularTest, SolveInPlace) {
   double rhs_and_solution[] = {1.0, 1.0, 2.0, 2.0};
-  const double expected[] = { -1.4706, -1.0962, 6.6667, 2.2477};
+  const double expected[] = {-1.4706, -1.0962, 6.6667, 2.2477};
 
-  SolveUpperTriangularInPlace<int>(cols.size() - 1,
-                                   &rows[0],
-                                   &cols[0],
-                                   &values[0],
-                                   rhs_and_solution);
+  SolveUpperTriangularInPlace<int>(
+      cols.size() - 1, &rows[0], &cols[0], &values[0], rhs_and_solution);
 
   for (int i = 0; i < 4; ++i) {
     EXPECT_NEAR(rhs_and_solution[i], expected[i], 1e-4) << i;
@@ -218,13 +217,10 @@
 
 TEST_F(SolveUpperTriangularTest, TransposeSolveInPlace) {
   double rhs_and_solution[] = {1.0, 1.0, 2.0, 2.0};
-  double expected[] = {1.970288,  1.242498,  6.081864, -0.057255};
+  double expected[] = {1.970288, 1.242498, 6.081864, -0.057255};
 
-  SolveUpperTriangularTransposeInPlace<int>(cols.size() - 1,
-                                            &rows[0],
-                                            &cols[0],
-                                            &values[0],
-                                            rhs_and_solution);
+  SolveUpperTriangularTransposeInPlace<int>(
+      cols.size() - 1, &rows[0], &cols[0], &values[0], rhs_and_solution);
 
   for (int i = 0; i < 4; ++i) {
     EXPECT_NEAR(rhs_and_solution[i], expected[i], 1e-4) << i;
@@ -233,18 +229,16 @@
 
 TEST_F(SolveUpperTriangularTest, RTRSolveWithSparseRHS) {
   double solution[4];
+  // clang-format off
   double expected[] = { 6.8420e+00,   1.0057e+00,  -1.4907e-16,  -1.9335e+00,
                         1.0057e+00,   2.2275e+00,  -1.9493e+00,  -6.5693e-01,
                         -1.4907e-16,  -1.9493e+00,   1.1111e+01,   9.7381e-17,
                         -1.9335e+00,  -6.5693e-01,   9.7381e-17,   1.2631e+00 };
+  // clang-format on
 
   for (int i = 0; i < 4; ++i) {
-    SolveRTRWithSparseRHS<int>(cols.size() - 1,
-                               &rows[0],
-                               &cols[0],
-                               &values[0],
-                               i,
-                               solution);
+    SolveRTRWithSparseRHS<int>(
+        cols.size() - 1, &rows[0], &cols[0], &values[0], i, solution);
     for (int j = 0; j < 4; ++j) {
       EXPECT_NEAR(solution[j], expected[4 * i + j], 1e-3) << i;
     }
diff --git a/internal/ceres/compressed_row_jacobian_writer.cc b/internal/ceres/compressed_row_jacobian_writer.cc
index 1fc0116..8e7e3e7 100644
--- a/internal/ceres/compressed_row_jacobian_writer.cc
+++ b/internal/ceres/compressed_row_jacobian_writer.cc
@@ -44,23 +44,21 @@
 namespace ceres {
 namespace internal {
 
+using std::adjacent_find;
 using std::make_pair;
 using std::pair;
 using std::vector;
-using std::adjacent_find;
 
 void CompressedRowJacobianWriter::PopulateJacobianRowAndColumnBlockVectors(
     const Program* program, CompressedRowSparseMatrix* jacobian) {
-  const vector<ParameterBlock*>& parameter_blocks =
-      program->parameter_blocks();
+  const vector<ParameterBlock*>& parameter_blocks = program->parameter_blocks();
   vector<int>& col_blocks = *(jacobian->mutable_col_blocks());
   col_blocks.resize(parameter_blocks.size());
   for (int i = 0; i < parameter_blocks.size(); ++i) {
     col_blocks[i] = parameter_blocks[i]->LocalSize();
   }
 
-  const vector<ResidualBlock*>& residual_blocks =
-      program->residual_blocks();
+  const vector<ResidualBlock*>& residual_blocks = program->residual_blocks();
   vector<int>& row_blocks = *(jacobian->mutable_row_blocks());
   row_blocks.resize(residual_blocks.size());
   for (int i = 0; i < residual_blocks.size(); ++i) {
@@ -69,11 +67,10 @@
 }
 
 void CompressedRowJacobianWriter::GetOrderedParameterBlocks(
-      const Program* program,
-      int residual_id,
-      vector<pair<int, int>>* evaluated_jacobian_blocks) {
-  const ResidualBlock* residual_block =
-      program->residual_blocks()[residual_id];
+    const Program* program,
+    int residual_id,
+    vector<pair<int, int>>* evaluated_jacobian_blocks) {
+  const ResidualBlock* residual_block = program->residual_blocks()[residual_id];
   const int num_parameter_blocks = residual_block->NumParameterBlocks();
 
   for (int j = 0; j < num_parameter_blocks; ++j) {
@@ -88,8 +85,7 @@
 }
 
 SparseMatrix* CompressedRowJacobianWriter::CreateJacobian() const {
-  const vector<ResidualBlock*>& residual_blocks =
-      program_->residual_blocks();
+  const vector<ResidualBlock*>& residual_blocks = program_->residual_blocks();
 
   int total_num_residuals = program_->NumResiduals();
   int total_num_effective_parameters = program_->NumEffectiveParameters();
@@ -112,11 +108,10 @@
   // Allocate more space than needed to store the jacobian so that when the LM
   // algorithm adds the diagonal, no reallocation is necessary. This reduces
   // peak memory usage significantly.
-  CompressedRowSparseMatrix* jacobian =
-      new CompressedRowSparseMatrix(
-          total_num_residuals,
-          total_num_effective_parameters,
-          num_jacobian_nonzeros + total_num_effective_parameters);
+  CompressedRowSparseMatrix* jacobian = new CompressedRowSparseMatrix(
+      total_num_residuals,
+      total_num_effective_parameters,
+      num_jacobian_nonzeros + total_num_effective_parameters);
 
   // At this stage, the CompressedRowSparseMatrix is an invalid state. But this
   // seems to be the only way to construct it without doing a memory copy.
@@ -148,8 +143,7 @@
       std::string parameter_block_description;
       for (int j = 0; j < num_parameter_blocks; ++j) {
         ParameterBlock* parameter_block = residual_block->parameter_blocks()[j];
-        parameter_block_description +=
-            parameter_block->ToString() + "\n";
+        parameter_block_description += parameter_block->ToString() + "\n";
       }
       LOG(FATAL) << "Ceres internal error: "
                  << "Duplicate parameter blocks detected in a cost function. "
@@ -196,7 +190,7 @@
 
 void CompressedRowJacobianWriter::Write(int residual_id,
                                         int residual_offset,
-                                        double **jacobians,
+                                        double** jacobians,
                                         SparseMatrix* base_jacobian) {
   CompressedRowSparseMatrix* jacobian =
       down_cast<CompressedRowSparseMatrix*>(base_jacobian);
diff --git a/internal/ceres/compressed_row_jacobian_writer.h b/internal/ceres/compressed_row_jacobian_writer.h
index 9fb414e..b1251ca 100644
--- a/internal/ceres/compressed_row_jacobian_writer.h
+++ b/internal/ceres/compressed_row_jacobian_writer.h
@@ -50,8 +50,7 @@
  public:
   CompressedRowJacobianWriter(Evaluator::Options /* ignored */,
                               Program* program)
-    : program_(program) {
-  }
+      : program_(program) {}
 
   // PopulateJacobianRowAndColumnBlockVectors sets col_blocks and
   // row_blocks for a CompressedRowSparseMatrix, based on the
@@ -64,8 +63,7 @@
   // (Jacobian writers do not fall under any type hierarchy; they only
   // have to provide an interface as specified in program_evaluator.h).
   static void PopulateJacobianRowAndColumnBlockVectors(
-      const Program* program,
-      CompressedRowSparseMatrix* jacobian);
+      const Program* program, CompressedRowSparseMatrix* jacobian);
 
   // It is necessary to determine the order of the jacobian blocks
   // before copying them into a CompressedRowSparseMatrix (or derived
@@ -99,7 +97,7 @@
 
   void Write(int residual_id,
              int residual_offset,
-             double **jacobians,
+             double** jacobians,
              SparseMatrix* base_jacobian);
 
  private:
diff --git a/internal/ceres/compressed_row_sparse_matrix.cc b/internal/ceres/compressed_row_sparse_matrix.cc
index e56de16..900586c 100644
--- a/internal/ceres/compressed_row_sparse_matrix.cc
+++ b/internal/ceres/compressed_row_sparse_matrix.cc
@@ -33,6 +33,7 @@
 #include <algorithm>
 #include <numeric>
 #include <vector>
+
 #include "ceres/crs_matrix.h"
 #include "ceres/internal/port.h"
 #include "ceres/random.h"
diff --git a/internal/ceres/compressed_row_sparse_matrix.h b/internal/ceres/compressed_row_sparse_matrix.h
index 2b51b9b..0a1b945 100644
--- a/internal/ceres/compressed_row_sparse_matrix.h
+++ b/internal/ceres/compressed_row_sparse_matrix.h
@@ -32,6 +32,7 @@
 #define CERES_INTERNAL_COMPRESSED_ROW_SPARSE_MATRIX_H_
 
 #include <vector>
+
 #include "ceres/internal/port.h"
 #include "ceres/sparse_matrix.h"
 #include "ceres/types.h"
@@ -45,7 +46,7 @@
 
 class TripletSparseMatrix;
 
-class CompressedRowSparseMatrix : public SparseMatrix {
+class CERES_EXPORT_INTERNAL CompressedRowSparseMatrix : public SparseMatrix {
  public:
   enum StorageType {
     UNSYMMETRIC,
@@ -100,18 +101,18 @@
 
   // SparseMatrix interface.
   virtual ~CompressedRowSparseMatrix();
-  virtual void SetZero();
-  virtual void RightMultiply(const double* x, double* y) const;
-  virtual void LeftMultiply(const double* x, double* y) const;
-  virtual void SquaredColumnNorm(double* x) const;
-  virtual void ScaleColumns(const double* scale);
-  virtual void ToDenseMatrix(Matrix* dense_matrix) const;
-  virtual void ToTextFile(FILE* file) const;
-  virtual int num_rows() const { return num_rows_; }
-  virtual int num_cols() const { return num_cols_; }
-  virtual int num_nonzeros() const { return rows_[num_rows_]; }
-  virtual const double* values() const { return &values_[0]; }
-  virtual double* mutable_values() { return &values_[0]; }
+  void SetZero() final;
+  void RightMultiply(const double* x, double* y) const final;
+  void LeftMultiply(const double* x, double* y) const final;
+  void SquaredColumnNorm(double* x) const final;
+  void ScaleColumns(const double* scale) final;
+  void ToDenseMatrix(Matrix* dense_matrix) const final;
+  void ToTextFile(FILE* file) const final;
+  int num_rows() const final { return num_rows_; }
+  int num_cols() const final { return num_cols_; }
+  int num_nonzeros() const final { return rows_[num_rows_]; }
+  const double* values() const final { return &values_[0]; }
+  double* mutable_values() final { return &values_[0]; }
 
   // Delete the bottom delta_rows.
   // num_rows -= delta_rows
diff --git a/internal/ceres/compressed_row_sparse_matrix_test.cc b/internal/ceres/compressed_row_sparse_matrix_test.cc
index cf6e2e4..91f3ba4 100644
--- a/internal/ceres/compressed_row_sparse_matrix_test.cc
+++ b/internal/ceres/compressed_row_sparse_matrix_test.cc
@@ -32,6 +32,8 @@
 
 #include <memory>
 #include <numeric>
+
+#include "Eigen/SparseCore"
 #include "ceres/casts.h"
 #include "ceres/crs_matrix.h"
 #include "ceres/internal/eigen.h"
@@ -41,14 +43,12 @@
 #include "glog/logging.h"
 #include "gtest/gtest.h"
 
-#include "Eigen/SparseCore"
-
 namespace ceres {
 namespace internal {
 
 using std::vector;
 
-void CompareMatrices(const SparseMatrix* a, const SparseMatrix* b) {
+static void CompareMatrices(const SparseMatrix* a, const SparseMatrix* b) {
   EXPECT_EQ(a->num_rows(), b->num_rows());
   EXPECT_EQ(a->num_cols(), b->num_cols());
 
@@ -71,7 +71,7 @@
 
 class CompressedRowSparseMatrixTest : public ::testing::Test {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     std::unique_ptr<LinearLeastSquaresProblem> problem(
         CreateLinearLeastSquaresProblemFromId(1));
 
@@ -380,7 +380,7 @@
 
 typedef ::testing::tuple<CompressedRowSparseMatrix::StorageType> Param;
 
-std::string ParamInfoToString(testing::TestParamInfo<Param> info) {
+static std::string ParamInfoToString(testing::TestParamInfo<Param> info) {
   if (::testing::get<0>(info.param) ==
       CompressedRowSparseMatrix::UPPER_TRIANGULAR) {
     return "UPPER";
@@ -445,16 +445,17 @@
                   0.0,
                   std::numeric_limits<double>::epsilon() * 10)
           << "\n"
-          << dense
-          << "x:\n"
+          << dense << "x:\n"
           << x.transpose() << "\n"
-          << "expected: \n" << expected_y.transpose() << "\n"
-          << "actual: \n" << actual_y.transpose();
+          << "expected: \n"
+          << expected_y.transpose() << "\n"
+          << "actual: \n"
+          << actual_y.transpose();
     }
   }
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CompressedRowSparseMatrix,
     RightMultiplyTest,
     ::testing::Values(CompressedRowSparseMatrix::LOWER_TRIANGULAR,
@@ -513,16 +514,17 @@
                   0.0,
                   std::numeric_limits<double>::epsilon() * 10)
           << "\n"
-          << dense
-          << "x\n"
+          << dense << "x\n"
           << x.transpose() << "\n"
-          << "expected: \n" << expected_y.transpose() << "\n"
-          << "actual: \n" << actual_y.transpose();
+          << "expected: \n"
+          << expected_y.transpose() << "\n"
+          << "actual: \n"
+          << actual_y.transpose();
     }
   }
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CompressedRowSparseMatrix,
     LeftMultiplyTest,
     ::testing::Values(CompressedRowSparseMatrix::LOWER_TRIANGULAR,
@@ -579,14 +581,15 @@
                   0.0,
                   std::numeric_limits<double>::epsilon() * 10)
           << "\n"
-          << dense
-          << "expected: \n" << expected.transpose() << "\n"
-          << "actual: \n" << actual.transpose();
+          << dense << "expected: \n"
+          << expected.transpose() << "\n"
+          << "actual: \n"
+          << actual.transpose();
     }
   }
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CompressedRowSparseMatrix,
     SquaredColumnNormTest,
     ::testing::Values(CompressedRowSparseMatrix::LOWER_TRIANGULAR,
@@ -594,7 +597,6 @@
                       CompressedRowSparseMatrix::UNSYMMETRIC),
     ParamInfoToString);
 
-
 // TODO(sameeragarwal) Add tests for the random matrix creation methods.
 
 }  // namespace internal
diff --git a/internal/ceres/concurrent_queue.h b/internal/ceres/concurrent_queue.h
index 52e2903..a04d147 100644
--- a/internal/ceres/concurrent_queue.h
+++ b/internal/ceres/concurrent_queue.h
@@ -152,7 +152,6 @@
   bool wait_;
 };
 
-
 }  // namespace internal
 }  // namespace ceres
 
diff --git a/internal/ceres/concurrent_queue_test.cc b/internal/ceres/concurrent_queue_test.cc
index 698966a..430111a 100644
--- a/internal/ceres/concurrent_queue_test.cc
+++ b/internal/ceres/concurrent_queue_test.cc
@@ -31,13 +31,12 @@
 // This include must come before any #ifndef check on Ceres compile options.
 #include "ceres/internal/port.h"
 
-#ifdef CERES_USE_CXX11_THREADS
+#ifdef CERES_USE_CXX_THREADS
 
 #include <chrono>
 #include <thread>
 
 #include "ceres/concurrent_queue.h"
-
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -304,4 +303,4 @@
 }  // namespace internal
 }  // namespace ceres
 
-#endif // CERES_USE_CXX11_THREADS
+#endif  // CERES_USE_CXX_THREADS
diff --git a/internal/ceres/conditioned_cost_function.cc b/internal/ceres/conditioned_cost_function.cc
index d933ad7..fb4c52a 100644
--- a/internal/ceres/conditioned_cost_function.cc
+++ b/internal/ceres/conditioned_cost_function.cc
@@ -68,7 +68,8 @@
 
 ConditionedCostFunction::~ConditionedCostFunction() {
   if (ownership_ == TAKE_OWNERSHIP) {
-    STLDeleteUniqueContainerPointers(conditioners_.begin(), conditioners_.end());
+    STLDeleteUniqueContainerPointers(conditioners_.begin(),
+                                     conditioners_.end());
   } else {
     wrapped_cost_function_.release();
   }
@@ -77,8 +78,8 @@
 bool ConditionedCostFunction::Evaluate(double const* const* parameters,
                                        double* residuals,
                                        double** jacobians) const {
-  bool success = wrapped_cost_function_->Evaluate(parameters, residuals,
-                                                  jacobians);
+  bool success =
+      wrapped_cost_function_->Evaluate(parameters, residuals, jacobians);
   if (!success) {
     return false;
   }
@@ -102,9 +103,8 @@
 
       double unconditioned_residual = residuals[r];
       double* parameter_pointer = &unconditioned_residual;
-      success = conditioners_[r]->Evaluate(&parameter_pointer,
-                                           &residuals[r],
-                                           conditioner_derivative_pointer2);
+      success = conditioners_[r]->Evaluate(
+          &parameter_pointer, &residuals[r], conditioner_derivative_pointer2);
       if (!success) {
         return false;
       }
@@ -117,7 +117,8 @@
             int parameter_block_size =
                 wrapped_cost_function_->parameter_block_sizes()[i];
             VectorRef jacobian_row(jacobians[i] + r * parameter_block_size,
-                                   parameter_block_size, 1);
+                                   parameter_block_size,
+                                   1);
             jacobian_row *= conditioner_derivative;
           }
         }
diff --git a/internal/ceres/conditioned_cost_function_test.cc b/internal/ceres/conditioned_cost_function_test.cc
index 6297451..f21f84c 100644
--- a/internal/ceres/conditioned_cost_function_test.cc
+++ b/internal/ceres/conditioned_cost_function_test.cc
@@ -41,7 +41,7 @@
 namespace internal {
 
 // The size of the cost functions we build.
-static const int kTestCostFunctionSize = 3;
+static constexpr int kTestCostFunctionSize = 3;
 
 // A simple cost function: return ax + b.
 class LinearCostFunction : public CostFunction {
@@ -51,9 +51,9 @@
     mutable_parameter_block_sizes()->push_back(1);
   }
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     *residuals = **parameters * a_ + b_;
     if (jacobians && *jacobians) {
       **jacobians = a_;
@@ -125,7 +125,8 @@
   // Make a cost function that computes x - v2
   double v2[kTestCostFunctionSize];
   VectorRef v2_vector(v2, kTestCostFunctionSize, 1);
-  Matrix identity = Matrix::Identity(kTestCostFunctionSize, kTestCostFunctionSize);
+  Matrix identity =
+      Matrix::Identity(kTestCostFunctionSize, kTestCostFunctionSize);
   NormalPrior* difference_cost_function = new NormalPrior(identity, v2_vector);
   CostFunction* conditioner = new LinearCostFunction(2, 7);
   std::vector<CostFunction*> conditioners;
diff --git a/internal/ceres/conjugate_gradients_solver.cc b/internal/ceres/conjugate_gradients_solver.cc
index c6f85c1..3019628 100644
--- a/internal/ceres/conjugate_gradients_solver.cc
+++ b/internal/ceres/conjugate_gradients_solver.cc
@@ -41,6 +41,7 @@
 
 #include <cmath>
 #include <cstddef>
+
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_operator.h"
 #include "ceres/stringprintf.h"
@@ -51,16 +52,13 @@
 namespace internal {
 namespace {
 
-bool IsZeroOrInfinity(double x) {
-  return ((x == 0.0) || std::isinf(x));
-}
+bool IsZeroOrInfinity(double x) { return ((x == 0.0) || std::isinf(x)); }
 
 }  // namespace
 
 ConjugateGradientsSolver::ConjugateGradientsSolver(
     const LinearSolver::Options& options)
-    : options_(options) {
-}
+    : options_(options) {}
 
 LinearSolver::Summary ConjugateGradientsSolver::Solve(
     LinearOperator* A,
@@ -137,7 +135,10 @@
         summary.termination_type = LINEAR_SOLVER_FAILURE;
         summary.message = StringPrintf(
             "Numerical failure. beta = rho_n / rho_{n-1} = %e, "
-            "rho_n = %e, rho_{n-1} = %e", beta, rho, last_rho);
+            "rho_n = %e, rho_{n-1} = %e",
+            beta,
+            rho,
+            last_rho);
         break;
       }
       p = z + beta * p;
@@ -152,16 +153,20 @@
       summary.message = StringPrintf(
           "Matrix is indefinite, no more progress can be made. "
           "p'q = %e. |p| = %e, |q| = %e",
-          pq, p.norm(), q.norm());
+          pq,
+          p.norm(),
+          q.norm());
       break;
     }
 
     const double alpha = rho / pq;
     if (std::isinf(alpha)) {
       summary.termination_type = LINEAR_SOLVER_FAILURE;
-      summary.message =
-          StringPrintf("Numerical failure. alpha = rho / pq = %e, "
-                       "rho = %e, pq = %e.", alpha, rho, pq);
+      summary.message = StringPrintf(
+          "Numerical failure. alpha = rho / pq = %e, rho = %e, pq = %e.",
+          alpha,
+          rho,
+          pq);
       break;
     }
 
@@ -223,7 +228,7 @@
     Q0 = Q1;
 
     // Residual based termination.
-    norm_r = r. norm();
+    norm_r = r.norm();
     if (norm_r <= tol_r &&
         summary.num_iterations >= options_.min_num_iterations) {
       summary.termination_type = LINEAR_SOLVER_SUCCESS;
diff --git a/internal/ceres/conjugate_gradients_solver.h b/internal/ceres/conjugate_gradients_solver.h
index 434cde0..f79ca49 100644
--- a/internal/ceres/conjugate_gradients_solver.h
+++ b/internal/ceres/conjugate_gradients_solver.h
@@ -34,6 +34,7 @@
 #ifndef CERES_INTERNAL_CONJUGATE_GRADIENTS_SOLVER_H_
 #define CERES_INTERNAL_CONJUGATE_GRADIENTS_SOLVER_H_
 
+#include "ceres/internal/port.h"
 #include "ceres/linear_solver.h"
 
 namespace ceres {
@@ -54,13 +55,13 @@
 // For more details see the documentation for
 // LinearSolver::PerSolveOptions::r_tolerance and
 // LinearSolver::PerSolveOptions::q_tolerance in linear_solver.h.
-class ConjugateGradientsSolver : public LinearSolver {
+class CERES_EXPORT_INTERNAL ConjugateGradientsSolver : public LinearSolver {
  public:
   explicit ConjugateGradientsSolver(const LinearSolver::Options& options);
-  virtual Summary Solve(LinearOperator* A,
-                        const double* b,
-                        const LinearSolver::PerSolveOptions& per_solve_options,
-                        double* x);
+  Summary Solve(LinearOperator* A,
+                const double* b,
+                const LinearSolver::PerSolveOptions& per_solve_options,
+                double* x) final;
 
  private:
   const LinearSolver::Options options_;
diff --git a/internal/ceres/conjugate_gradients_solver_test.cc b/internal/ceres/conjugate_gradients_solver_test.cc
index 9311998..b11e522 100644
--- a/internal/ceres/conjugate_gradients_solver_test.cc
+++ b/internal/ceres/conjugate_gradients_solver_test.cc
@@ -31,21 +31,23 @@
 // TODO(sameeragarwal): More comprehensive testing with larger and
 // more badly conditioned problem.
 
-#include <memory>
-#include "gtest/gtest.h"
 #include "ceres/conjugate_gradients_solver.h"
+
+#include <memory>
+
+#include "ceres/internal/eigen.h"
 #include "ceres/linear_solver.h"
 #include "ceres/triplet_sparse_matrix.h"
-#include "ceres/internal/eigen.h"
 #include "ceres/types.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
 
 TEST(ConjugateGradientTest, Solves3x3IdentitySystem) {
-  double diagonal[] = { 1.0, 1.0, 1.0 };
-  std::unique_ptr<TripletSparseMatrix>
-      A(TripletSparseMatrix::CreateSparseDiagonalMatrix(diagonal, 3));
+  double diagonal[] = {1.0, 1.0, 1.0};
+  std::unique_ptr<TripletSparseMatrix> A(
+      TripletSparseMatrix::CreateSparseDiagonalMatrix(diagonal, 3));
   Vector b(3);
   Vector x(3);
 
@@ -75,7 +77,6 @@
   ASSERT_DOUBLE_EQ(3, x(2));
 }
 
-
 TEST(ConjuateGradientTest, Solves3x3SymmetricSystem) {
   std::unique_ptr<TripletSparseMatrix> A(new TripletSparseMatrix(3, 3, 9));
   Vector b(3);
diff --git a/internal/ceres/context.cc b/internal/ceres/context.cc
index e223201..55e7635 100644
--- a/internal/ceres/context.cc
+++ b/internal/ceres/context.cc
@@ -34,8 +34,6 @@
 
 namespace ceres {
 
-Context* Context::Create() {
-  return new internal::ContextImpl();
-}
+Context* Context::Create() { return new internal::ContextImpl(); }
 
 }  // namespace ceres
diff --git a/internal/ceres/context_impl.cc b/internal/ceres/context_impl.cc
index 1b9662f..20fe5cb 100644
--- a/internal/ceres/context_impl.cc
+++ b/internal/ceres/context_impl.cc
@@ -34,10 +34,9 @@
 namespace internal {
 
 void ContextImpl::EnsureMinimumThreads(int num_threads) {
-#ifdef CERES_USE_CXX11_THREADS
+#ifdef CERES_USE_CXX_THREADS
   thread_pool.Resize(num_threads);
-#endif  // CERES_USE_CXX11_THREADS
-
+#endif  // CERES_USE_CXX_THREADS
 }
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/context_impl.h b/internal/ceres/context_impl.h
index d83b77a..574d1ef 100644
--- a/internal/ceres/context_impl.h
+++ b/internal/ceres/context_impl.h
@@ -32,18 +32,20 @@
 #define CERES_INTERNAL_CONTEXT_IMPL_H_
 
 // This include must come before any #ifndef check on Ceres compile options.
+// clang-format off
 #include "ceres/internal/port.h"
+// clanf-format on
 
 #include "ceres/context.h"
 
-#ifdef CERES_USE_CXX11_THREADS
+#ifdef CERES_USE_CXX_THREADS
 #include "ceres/thread_pool.h"
-#endif  // CERES_USE_CXX11_THREADS
+#endif  // CERES_USE_CXX_THREADS
 
 namespace ceres {
 namespace internal {
 
-class ContextImpl : public Context {
+class CERES_EXPORT_INTERNAL ContextImpl : public Context {
  public:
   ContextImpl() {}
   ContextImpl(const ContextImpl&) = delete;
@@ -51,14 +53,14 @@
 
   virtual ~ContextImpl() {}
 
-  // When compiled with C++11 threading support, resize the thread pool to have
+  // When compiled with C++ threading support, resize the thread pool to have
   // at min(num_thread, num_hardware_threads) where num_hardware_threads is
   // defined by the hardware.  Otherwise this call is a no-op.
   void EnsureMinimumThreads(int num_threads);
 
-#ifdef CERES_USE_CXX11_THREADS
+#ifdef CERES_USE_CXX_THREADS
   ThreadPool thread_pool;
-#endif  // CERES_USE_CXX11_THREADS
+#endif  // CERES_USE_CXX_THREADS
 };
 
 }  // namespace internal
diff --git a/internal/ceres/coordinate_descent_minimizer.cc b/internal/ceres/coordinate_descent_minimizer.cc
index c5d56f3..93096ac 100644
--- a/internal/ceres/coordinate_descent_minimizer.cc
+++ b/internal/ceres/coordinate_descent_minimizer.cc
@@ -64,8 +64,7 @@
   CHECK(context_ != nullptr);
 }
 
-CoordinateDescentMinimizer::~CoordinateDescentMinimizer() {
-}
+CoordinateDescentMinimizer::~CoordinateDescentMinimizer() {}
 
 bool CoordinateDescentMinimizer::Init(
     const Program& program,
@@ -82,13 +81,13 @@
   map<int, set<double*>> group_to_elements = ordering.group_to_elements();
   for (const auto& g_t_e : group_to_elements) {
     const auto& elements = g_t_e.second;
-    for (double* parameter_block: elements) {
+    for (double* parameter_block : elements) {
       parameter_blocks_.push_back(parameter_map.find(parameter_block)->second);
       parameter_block_index[parameter_blocks_.back()] =
           parameter_blocks_.size() - 1;
     }
-    independent_set_offsets_.push_back(
-        independent_set_offsets_.back() + elements.size());
+    independent_set_offsets_.push_back(independent_set_offsets_.back() +
+                                       elements.size());
   }
 
   // The ordering does not have to contain all parameter blocks, so
@@ -126,10 +125,9 @@
   return true;
 }
 
-void CoordinateDescentMinimizer::Minimize(
-    const Minimizer::Options& options,
-    double* parameters,
-    Solver::Summary* summary) {
+void CoordinateDescentMinimizer::Minimize(const Minimizer::Options& options,
+                                          double* parameters,
+                                          Solver::Summary* summary) {
   // Set the state and mark all parameter blocks constant.
   for (int i = 0; i < parameter_blocks_.size(); ++i) {
     ParameterBlock* parameter_block = parameter_blocks_[i];
@@ -202,7 +200,7 @@
         });
   }
 
-  for (int i =  0; i < parameter_blocks_.size(); ++i) {
+  for (int i = 0; i < parameter_blocks_.size(); ++i) {
     parameter_blocks_[i]->SetVarying();
   }
 
@@ -251,10 +249,10 @@
   // Verify that each group is an independent set
   for (const auto& g_t_e : group_to_elements) {
     if (!program.IsParameterBlockSetIndependent(g_t_e.second)) {
-      *message =
-          StringPrintf("The user-provided "
-                       "parameter_blocks_for_inner_iterations does not "
-                       "form an independent set. Group Id: %d", g_t_e.first);
+      *message = StringPrintf(
+          "The user-provided parameter_blocks_for_inner_iterations does not "
+          "form an independent set. Group Id: %d",
+          g_t_e.first);
       return false;
     }
   }
diff --git a/internal/ceres/coordinate_descent_minimizer.h b/internal/ceres/coordinate_descent_minimizer.h
index 3bbcc2d..7d17d53 100644
--- a/internal/ceres/coordinate_descent_minimizer.h
+++ b/internal/ceres/coordinate_descent_minimizer.h
@@ -68,9 +68,9 @@
   // Minimizer interface.
   virtual ~CoordinateDescentMinimizer();
 
-  virtual void Minimize(const Minimizer::Options& options,
-                        double* parameters,
-                        Solver::Summary* summary);
+  void Minimize(const Minimizer::Options& options,
+                double* parameters,
+                Solver::Summary* summary) final;
 
   // Verify that each group in the ordering forms an independent set.
   static bool IsOrderingValid(const Program& program,
diff --git a/internal/ceres/corrector.cc b/internal/ceres/corrector.cc
index 4ac0dc3..6a79a06 100644
--- a/internal/ceres/corrector.cc
+++ b/internal/ceres/corrector.cc
@@ -30,8 +30,9 @@
 
 #include "ceres/corrector.h"
 
-#include <cstddef>
 #include <cmath>
+#include <cstddef>
+
 #include "ceres/internal/eigen.h"
 #include "glog/logging.h"
 
@@ -147,9 +148,9 @@
     }
 
     for (int r = 0; r < num_rows; ++r) {
-      jacobian[r * num_cols + c] = sqrt_rho1_ *
-          (jacobian[r * num_cols + c] -
-           alpha_sq_norm_ * residuals[r] * r_transpose_j);
+      jacobian[r * num_cols + c] =
+          sqrt_rho1_ * (jacobian[r * num_cols + c] -
+                        alpha_sq_norm_ * residuals[r] * r_transpose_j);
     }
   }
 }
diff --git a/internal/ceres/corrector.h b/internal/ceres/corrector.h
index a5b03dd..3e11cdc 100644
--- a/internal/ceres/corrector.h
+++ b/internal/ceres/corrector.h
@@ -35,6 +35,8 @@
 #ifndef CERES_INTERNAL_CORRECTOR_H_
 #define CERES_INTERNAL_CORRECTOR_H_
 
+#include "ceres/internal/port.h"
+
 namespace ceres {
 namespace internal {
 
@@ -46,7 +48,7 @@
 // gauss newton approximation and then take its square root to get the
 // corresponding corrections to the residual and jacobian.  For the
 // full expressions see Eq. 10 and 11 in BANS by Triggs et al.
-class Corrector {
+class CERES_EXPORT_INTERNAL Corrector {
  public:
   // The constructor takes the squared norm, the value, the first and
   // second derivatives of the LossFunction. It precalculates some of
diff --git a/internal/ceres/corrector_test.cc b/internal/ceres/corrector_test.cc
index a6581fd..951041e 100644
--- a/internal/ceres/corrector_test.cc
+++ b/internal/ceres/corrector_test.cc
@@ -32,11 +32,12 @@
 
 #include <algorithm>
 #include <cmath>
-#include <cstring>
 #include <cstdlib>
-#include "gtest/gtest.h"
-#include "ceres/random.h"
+#include <cstring>
+
 #include "ceres/internal/eigen.h"
+#include "ceres/random.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
@@ -44,15 +45,13 @@
 // If rho[1] is zero, the Corrector constructor should crash.
 TEST(Corrector, ZeroGradientDeathTest) {
   const double kRho[] = {0.0, 0.0, 1.0};
-  EXPECT_DEATH_IF_SUPPORTED({Corrector c(1.0, kRho);},
-               ".*");
+  EXPECT_DEATH_IF_SUPPORTED({ Corrector c(1.0, kRho); }, ".*");
 }
 
 // If rho[1] is negative, the Corrector constructor should crash.
 TEST(Corrector, NegativeGradientDeathTest) {
   const double kRho[] = {0.0, -0.1, 1.0};
-  EXPECT_DEATH_IF_SUPPORTED({Corrector c(1.0, kRho);},
-               ".*");
+  EXPECT_DEATH_IF_SUPPORTED({ Corrector c(1.0, kRho); }, ".*");
 }
 
 TEST(Corrector, ScalarCorrection) {
@@ -68,8 +67,7 @@
 
   // Thus the expected value of the residual is
   // residual[i] * sqrt(kRho[1]) / (1.0 - kAlpha).
-  const double kExpectedResidual =
-      residuals * sqrt(kRho[1]) / (1 - kAlpha);
+  const double kExpectedResidual = residuals * sqrt(kRho[1]) / (1 - kAlpha);
 
   // The jacobian in this case will be
   // sqrt(kRho[1]) * (1 - kAlpha) * jacobian.
@@ -123,13 +121,11 @@
 
   // Thus the expected value of the residual is
   // residual[i] * sqrt(kRho[1]) / (1.0 - kAlpha).
-  const double kExpectedResidual =
-      residuals * sqrt(kRho[1]) / (1.0 - kAlpha);
+  const double kExpectedResidual = residuals * sqrt(kRho[1]) / (1.0 - kAlpha);
 
   // The jacobian in this case will be scaled by
   // sqrt(rho[1]) * (1 - alpha) * J.
-  const double kExpectedJacobian = sqrt(kRho[1]) *
-      (1.0 - kAlpha) * jacobian;
+  const double kExpectedJacobian = sqrt(kRho[1]) * (1.0 - kAlpha) * jacobian;
 
   Corrector c(sq_norm, kRho);
   c.CorrectJacobian(1, 1, &residuals, &jacobian);
@@ -168,10 +164,8 @@
   srand(5);
   for (int iter = 0; iter < 10000; ++iter) {
     // Initialize the jacobian and residual.
-    for (int i = 0; i < 2 * 3; ++i)
-      jacobian[i] = RandDouble();
-    for (int i = 0; i < 3; ++i)
-      residuals[i] = RandDouble();
+    for (int i = 0; i < 2 * 3; ++i) jacobian[i] = RandDouble();
+    for (int i = 0; i < 3; ++i) residuals[i] = RandDouble();
 
     const double sq_norm = res.dot(res);
 
@@ -188,19 +182,19 @@
 
     // Ground truth values.
     g_res = sqrt(rho[1]) / (1.0 - kAlpha) * res;
-    g_jac = sqrt(rho[1]) * (jac - kAlpha / sq_norm *
-                            res * res.transpose() * jac);
+    g_jac =
+        sqrt(rho[1]) * (jac - kAlpha / sq_norm * res * res.transpose() * jac);
 
     g_grad = rho[1] * jac.transpose() * res;
     g_hess = rho[1] * jac.transpose() * jac +
-        2.0 * rho[2] * jac.transpose() * res * res.transpose() * jac;
+             2.0 * rho[2] * jac.transpose() * res * res.transpose() * jac;
 
     Corrector c(sq_norm, rho);
     c.CorrectJacobian(3, 2, residuals, jacobian);
     c.CorrectResiduals(3, residuals);
 
     // Corrected gradient and hessian.
-    c_grad  = jac.transpose() * res;
+    c_grad = jac.transpose() * res;
     c_hess = jac.transpose() * jac;
 
     ASSERT_NEAR((g_res - res).norm(), 0.0, 1e-10);
@@ -236,8 +230,7 @@
   srand(5);
   for (int iter = 0; iter < 10000; ++iter) {
     // Initialize the jacobian.
-    for (int i = 0; i < 2 * 3; ++i)
-      jacobian[i] = RandDouble();
+    for (int i = 0; i < 2 * 3; ++i) jacobian[i] = RandDouble();
 
     // Zero residuals
     res.setZero();
@@ -254,7 +247,7 @@
 
     g_grad = rho[1] * jac.transpose() * res;
     g_hess = rho[1] * jac.transpose() * jac +
-        2.0 * rho[2] * jac.transpose() * res * res.transpose() * jac;
+             2.0 * rho[2] * jac.transpose() * res * res.transpose() * jac;
 
     Corrector c(sq_norm, rho);
     c.CorrectJacobian(3, 2, residuals, jacobian);
diff --git a/internal/ceres/cost_function_to_functor_test.cc b/internal/ceres/cost_function_to_functor_test.cc
index 52687ea..11f47e3 100644
--- a/internal/ceres/cost_function_to_functor_test.cc
+++ b/internal/ceres/cost_function_to_functor_test.cc
@@ -32,9 +32,10 @@
 
 #include <cstdint>
 #include <memory>
+
+#include "ceres/autodiff_cost_function.h"
 #include "ceres/dynamic_autodiff_cost_function.h"
 #include "ceres/dynamic_cost_function_to_functor.h"
-#include "ceres/autodiff_cost_function.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -43,8 +44,9 @@
 using std::vector;
 const double kTolerance = 1e-18;
 
-void ExpectCostFunctionsAreEqual(const CostFunction& cost_function,
-                                 const CostFunction& actual_cost_function) {
+static void ExpectCostFunctionsAreEqual(
+    const CostFunction& cost_function,
+    const CostFunction& actual_cost_function) {
   EXPECT_EQ(cost_function.num_residuals(),
             actual_cost_function.num_residuals());
   const int num_residuals = cost_function.num_residuals();
@@ -52,8 +54,7 @@
       cost_function.parameter_block_sizes();
   const vector<int32_t>& actual_parameter_block_sizes =
       actual_cost_function.parameter_block_sizes();
-  EXPECT_EQ(parameter_block_sizes.size(),
-            actual_parameter_block_sizes.size());
+  EXPECT_EQ(parameter_block_sizes.size(), actual_parameter_block_sizes.size());
 
   int num_parameters = 0;
   for (int i = 0; i < parameter_block_sizes.size(); ++i) {
@@ -67,11 +68,12 @@
   }
 
   std::unique_ptr<double[]> residuals(new double[num_residuals]);
-  std::unique_ptr<double[]> jacobians(new double[num_parameters * num_residuals]);
+  std::unique_ptr<double[]> jacobians(
+      new double[num_parameters * num_residuals]);
 
   std::unique_ptr<double[]> actual_residuals(new double[num_residuals]);
-  std::unique_ptr<double[]> actual_jacobians
-      (new double[num_parameters * num_residuals]);
+  std::unique_ptr<double[]> actual_jacobians(
+      new double[num_parameters * num_residuals]);
 
   std::unique_ptr<double*[]> parameter_blocks(
       new double*[parameter_block_sizes.size()]);
@@ -89,19 +91,17 @@
     num_parameters += parameter_block_sizes[i];
   }
 
-  EXPECT_TRUE(cost_function.Evaluate(parameter_blocks.get(),
-                                     residuals.get(), NULL));
-  EXPECT_TRUE(actual_cost_function.Evaluate(parameter_blocks.get(),
-                                            actual_residuals.get(), NULL));
+  EXPECT_TRUE(
+      cost_function.Evaluate(parameter_blocks.get(), residuals.get(), NULL));
+  EXPECT_TRUE(actual_cost_function.Evaluate(
+      parameter_blocks.get(), actual_residuals.get(), NULL));
   for (int i = 0; i < num_residuals; ++i) {
     EXPECT_NEAR(residuals[i], actual_residuals[i], kTolerance)
         << "residual id: " << i;
   }
 
-
-  EXPECT_TRUE(cost_function.Evaluate(parameter_blocks.get(),
-                                     residuals.get(),
-                                     jacobian_blocks.get()));
+  EXPECT_TRUE(cost_function.Evaluate(
+      parameter_blocks.get(), residuals.get(), jacobian_blocks.get()));
   EXPECT_TRUE(actual_cost_function.Evaluate(parameter_blocks.get(),
                                             actual_residuals.get(),
                                             actual_jacobian_blocks.get()));
@@ -112,8 +112,8 @@
 
   for (int i = 0; i < num_residuals * num_parameters; ++i) {
     EXPECT_NEAR(jacobians[i], actual_jacobians[i], kTolerance)
-        << "jacobian : " << i << " "
-        << jacobians[i] << " " << actual_jacobians[i];
+        << "jacobian : " << i << " " << jacobians[i] << " "
+        << actual_jacobians[i];
   }
 }
 
@@ -131,8 +131,8 @@
  public:
   template <typename T>
   bool operator()(const T* x1, const T* x2, T* residuals) const {
-    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0];
-    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1];
+    residuals[0] = x1[0] * x1[0] + x2[0] * x2[0];
+    residuals[1] = x1[1] * x1[1] + x2[1] * x2[1];
     return true;
   }
 };
@@ -141,8 +141,8 @@
  public:
   template <typename T>
   bool operator()(const T* x1, const T* x2, const T* x3, T* residuals) const {
-    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0];
-    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1];
+    residuals[0] = x1[0] * x1[0] + x2[0] * x2[0] + x3[0] * x3[0];
+    residuals[1] = x1[1] * x1[1] + x2[1] * x2[1] + x3[1] * x3[1];
     return true;
   }
 };
@@ -150,12 +150,12 @@
 struct FourParameterBlockFunctor {
  public:
   template <typename T>
-  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
-                  T* residuals) const {
-    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
-        + x4[0] * x4[0];
-    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
-        + x4[1] * x4[1];
+  bool operator()(
+      const T* x1, const T* x2, const T* x3, const T* x4, T* residuals) const {
+    residuals[0] =
+        x1[0] * x1[0] + x2[0] * x2[0] + x3[0] * x3[0] + x4[0] * x4[0];
+    residuals[1] =
+        x1[1] * x1[1] + x2[1] * x2[1] + x3[1] * x3[1] + x4[1] * x4[1];
     return true;
   }
 };
@@ -163,12 +163,16 @@
 struct FiveParameterBlockFunctor {
  public:
   template <typename T>
-  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
-                  const T* x5, T* residuals) const {
-    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
-        + x4[0] * x4[0] + x5[0] * x5[0];
-    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
-        + x4[1] * x4[1] + x5[1] * x5[1];
+  bool operator()(const T* x1,
+                  const T* x2,
+                  const T* x3,
+                  const T* x4,
+                  const T* x5,
+                  T* residuals) const {
+    residuals[0] = x1[0] * x1[0] + x2[0] * x2[0] + x3[0] * x3[0] +
+                   x4[0] * x4[0] + x5[0] * x5[0];
+    residuals[1] = x1[1] * x1[1] + x2[1] * x2[1] + x3[1] * x3[1] +
+                   x4[1] * x4[1] + x5[1] * x5[1];
     return true;
   }
 };
@@ -176,12 +180,17 @@
 struct SixParameterBlockFunctor {
  public:
   template <typename T>
-  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
-                  const T* x5, const T* x6,  T* residuals) const {
-    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
-        + x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0];
-    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
-        + x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1];
+  bool operator()(const T* x1,
+                  const T* x2,
+                  const T* x3,
+                  const T* x4,
+                  const T* x5,
+                  const T* x6,
+                  T* residuals) const {
+    residuals[0] = x1[0] * x1[0] + x2[0] * x2[0] + x3[0] * x3[0] +
+                   x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0];
+    residuals[1] = x1[1] * x1[1] + x2[1] * x2[1] + x3[1] * x3[1] +
+                   x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1];
     return true;
   }
 };
@@ -189,12 +198,20 @@
 struct SevenParameterBlockFunctor {
  public:
   template <typename T>
-  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
-                  const T* x5, const T* x6, const T* x7, T* residuals) const {
-    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
-        + x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0] + x7[0] * x7[0];
-    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
-        + x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1] + x7[1] * x7[1];
+  bool operator()(const T* x1,
+                  const T* x2,
+                  const T* x3,
+                  const T* x4,
+                  const T* x5,
+                  const T* x6,
+                  const T* x7,
+                  T* residuals) const {
+    residuals[0] = x1[0] * x1[0] + x2[0] * x2[0] + x3[0] * x3[0] +
+                   x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0] +
+                   x7[0] * x7[0];
+    residuals[1] = x1[1] * x1[1] + x2[1] * x2[1] + x3[1] * x3[1] +
+                   x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1] +
+                   x7[1] * x7[1];
     return true;
   }
 };
@@ -202,15 +219,21 @@
 struct EightParameterBlockFunctor {
  public:
   template <typename T>
-  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
-                  const T* x5, const T* x6, const T* x7, const T* x8,
+  bool operator()(const T* x1,
+                  const T* x2,
+                  const T* x3,
+                  const T* x4,
+                  const T* x5,
+                  const T* x6,
+                  const T* x7,
+                  const T* x8,
                   T* residuals) const {
-    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
-        + x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0] + x7[0] * x7[0]
-        + x8[0] * x8[0];
-    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
-        + x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1] + x7[1] * x7[1]
-        + x8[1] * x8[1];
+    residuals[0] = x1[0] * x1[0] + x2[0] * x2[0] + x3[0] * x3[0] +
+                   x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0] +
+                   x7[0] * x7[0] + x8[0] * x8[0];
+    residuals[1] = x1[1] * x1[1] + x2[1] * x2[1] + x3[1] * x3[1] +
+                   x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1] +
+                   x7[1] * x7[1] + x8[1] * x8[1];
     return true;
   }
 };
@@ -218,15 +241,22 @@
 struct NineParameterBlockFunctor {
  public:
   template <typename T>
-  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
-                  const T* x5, const T* x6, const T* x7, const T* x8,
-                  const T* x9, T* residuals) const {
-    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
-        + x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0] + x7[0] * x7[0]
-        + x8[0] * x8[0] + x9[0] * x9[0];
-    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
-        + x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1] + x7[1] * x7[1]
-        + x8[1] * x8[1] + x9[1] * x9[1];
+  bool operator()(const T* x1,
+                  const T* x2,
+                  const T* x3,
+                  const T* x4,
+                  const T* x5,
+                  const T* x6,
+                  const T* x7,
+                  const T* x8,
+                  const T* x9,
+                  T* residuals) const {
+    residuals[0] = x1[0] * x1[0] + x2[0] * x2[0] + x3[0] * x3[0] +
+                   x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0] +
+                   x7[0] * x7[0] + x8[0] * x8[0] + x9[0] * x9[0];
+    residuals[1] = x1[1] * x1[1] + x2[1] * x2[1] + x3[1] * x3[1] +
+                   x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1] +
+                   x7[1] * x7[1] + x8[1] * x8[1] + x9[1] * x9[1];
     return true;
   }
 };
@@ -234,15 +264,25 @@
 struct TenParameterBlockFunctor {
  public:
   template <typename T>
-  bool operator()(const T* x1, const T* x2, const T* x3, const T* x4,
-                  const T* x5, const T* x6, const T* x7, const T* x8,
-                  const T* x9, const T* x10, T* residuals) const {
-    residuals[0] = x1[0] * x1[0]  + x2[0] * x2[0] + x3[0] * x3[0]
-        + x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0] + x7[0] * x7[0]
-        + x8[0] * x8[0] + x9[0] * x9[0] + x10[0] * x10[0];
-    residuals[1] = x1[1] * x1[1]  + x2[1] * x2[1] + x3[1] * x3[1]
-        + x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1] + x7[1] * x7[1]
-        + x8[1] * x8[1] + x9[1] * x9[1] + x10[1] * x10[1];
+  bool operator()(const T* x1,
+                  const T* x2,
+                  const T* x3,
+                  const T* x4,
+                  const T* x5,
+                  const T* x6,
+                  const T* x7,
+                  const T* x8,
+                  const T* x9,
+                  const T* x10,
+                  T* residuals) const {
+    residuals[0] = x1[0] * x1[0] + x2[0] * x2[0] + x3[0] * x3[0] +
+                   x4[0] * x4[0] + x5[0] * x5[0] + x6[0] * x6[0] +
+                   x7[0] * x7[0] + x8[0] * x8[0] + x9[0] * x9[0] +
+                   x10[0] * x10[0];
+    residuals[1] = x1[1] * x1[1] + x2[1] * x2[1] + x3[1] * x3[1] +
+                   x4[1] * x4[1] + x5[1] * x5[1] + x6[1] * x6[1] +
+                   x7[1] * x7[1] + x8[1] * x8[1] + x9[1] * x9[1] +
+                   x10[1] * x10[1];
     return true;
   }
 };
@@ -259,75 +299,78 @@
   }
 };
 
-#define TEST_BODY(NAME)                                                 \
-  TEST(CostFunctionToFunctor, NAME) {                                   \
-    std::unique_ptr<CostFunction> cost_function(                             \
-        new AutoDiffCostFunction<                                       \
-            CostFunctionToFunctor<2, PARAMETER_BLOCK_SIZES >,           \
-                2, PARAMETER_BLOCK_SIZES>(new CostFunctionToFunctor<    \
-                    2, PARAMETER_BLOCK_SIZES >(                         \
-                        new AutoDiffCostFunction<                       \
-                            NAME##Functor, 2, PARAMETER_BLOCK_SIZES >(  \
-                  new NAME##Functor))));                                \
-                                                                        \
-std::unique_ptr<CostFunction> actual_cost_function(                          \
-    new AutoDiffCostFunction<NAME##Functor, 2, PARAMETER_BLOCK_SIZES >( \
-        new NAME##Functor));                                            \
-ExpectCostFunctionsAreEqual(*cost_function, *actual_cost_function);     \
-}
+// Check that AutoDiff(Functor1) == AutoDiff(CostToFunctor(AutoDiff(Functor1)))
+#define TEST_BODY(Functor1)                                                    \
+  TEST(CostFunctionToFunctor, Functor1) {                                      \
+    typedef AutoDiffCostFunction<Functor1, 2, PARAMETER_BLOCK_SIZES>           \
+        CostFunction1;                                                         \
+    typedef CostFunctionToFunctor<2, PARAMETER_BLOCK_SIZES> FunctionToFunctor; \
+    typedef AutoDiffCostFunction<FunctionToFunctor, 2, PARAMETER_BLOCK_SIZES>  \
+        CostFunction2;                                                         \
+                                                                               \
+    std::unique_ptr<CostFunction> cost_function(new CostFunction2(             \
+        new FunctionToFunctor(new CostFunction1(new Functor1))));              \
+                                                                               \
+    std::unique_ptr<CostFunction> actual_cost_function(                        \
+        new CostFunction1(new Functor1));                                      \
+    ExpectCostFunctionsAreEqual(*cost_function, *actual_cost_function);        \
+  }
 
 #define PARAMETER_BLOCK_SIZES 2
-TEST_BODY(OneParameterBlock)
+TEST_BODY(OneParameterBlockFunctor)
 #undef PARAMETER_BLOCK_SIZES
 
-#define PARAMETER_BLOCK_SIZES 2,2
-TEST_BODY(TwoParameterBlock)
+#define PARAMETER_BLOCK_SIZES 2, 2
+TEST_BODY(TwoParameterBlockFunctor)
 #undef PARAMETER_BLOCK_SIZES
 
-#define PARAMETER_BLOCK_SIZES 2,2,2
-TEST_BODY(ThreeParameterBlock)
+#define PARAMETER_BLOCK_SIZES 2, 2, 2
+TEST_BODY(ThreeParameterBlockFunctor)
 #undef PARAMETER_BLOCK_SIZES
 
-#define PARAMETER_BLOCK_SIZES 2,2,2,2
-TEST_BODY(FourParameterBlock)
+#define PARAMETER_BLOCK_SIZES 2, 2, 2, 2
+TEST_BODY(FourParameterBlockFunctor)
 #undef PARAMETER_BLOCK_SIZES
 
-#define PARAMETER_BLOCK_SIZES 2,2,2,2,2
-TEST_BODY(FiveParameterBlock)
+#define PARAMETER_BLOCK_SIZES 2, 2, 2, 2, 2
+TEST_BODY(FiveParameterBlockFunctor)
 #undef PARAMETER_BLOCK_SIZES
 
-#define PARAMETER_BLOCK_SIZES 2,2,2,2,2,2
-TEST_BODY(SixParameterBlock)
+#define PARAMETER_BLOCK_SIZES 2, 2, 2, 2, 2, 2
+TEST_BODY(SixParameterBlockFunctor)
 #undef PARAMETER_BLOCK_SIZES
 
-#define PARAMETER_BLOCK_SIZES 2,2,2,2,2,2,2
-TEST_BODY(SevenParameterBlock)
+#define PARAMETER_BLOCK_SIZES 2, 2, 2, 2, 2, 2, 2
+TEST_BODY(SevenParameterBlockFunctor)
 #undef PARAMETER_BLOCK_SIZES
 
-#define PARAMETER_BLOCK_SIZES 2,2,2,2,2,2,2,2
-TEST_BODY(EightParameterBlock)
+#define PARAMETER_BLOCK_SIZES 2, 2, 2, 2, 2, 2, 2, 2
+TEST_BODY(EightParameterBlockFunctor)
 #undef PARAMETER_BLOCK_SIZES
 
-#define PARAMETER_BLOCK_SIZES 2,2,2,2,2,2,2,2,2
-TEST_BODY(NineParameterBlock)
+#define PARAMETER_BLOCK_SIZES 2, 2, 2, 2, 2, 2, 2, 2, 2
+TEST_BODY(NineParameterBlockFunctor)
 #undef PARAMETER_BLOCK_SIZES
 
-#define PARAMETER_BLOCK_SIZES 2,2,2,2,2,2,2,2,2,2
-TEST_BODY(TenParameterBlock)
+#define PARAMETER_BLOCK_SIZES 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+TEST_BODY(TenParameterBlockFunctor)
 #undef PARAMETER_BLOCK_SIZES
 
 #undef TEST_BODY
 
 TEST(CostFunctionToFunctor, DynamicNumberOfResiduals) {
   std::unique_ptr<CostFunction> cost_function(
-      new AutoDiffCostFunction<
-      CostFunctionToFunctor<ceres::DYNAMIC, 2, 2 >, ceres::DYNAMIC, 2, 2>(
-          new CostFunctionToFunctor<ceres::DYNAMIC, 2, 2 >(
-              new AutoDiffCostFunction<TwoParameterBlockFunctor, 2, 2, 2 >(
-                  new TwoParameterBlockFunctor)), 2));
+      new AutoDiffCostFunction<CostFunctionToFunctor<ceres::DYNAMIC, 2, 2>,
+                               ceres::DYNAMIC,
+                               2,
+                               2>(
+          new CostFunctionToFunctor<ceres::DYNAMIC, 2, 2>(
+              new AutoDiffCostFunction<TwoParameterBlockFunctor, 2, 2, 2>(
+                  new TwoParameterBlockFunctor)),
+          2));
 
   std::unique_ptr<CostFunction> actual_cost_function(
-      new AutoDiffCostFunction<TwoParameterBlockFunctor, 2, 2, 2 >(
+      new AutoDiffCostFunction<TwoParameterBlockFunctor, 2, 2, 2>(
           new TwoParameterBlockFunctor));
   ExpectCostFunctionsAreEqual(*cost_function, *actual_cost_function);
 }
@@ -335,8 +378,8 @@
 TEST(CostFunctionToFunctor, DynamicCostFunctionToFunctor) {
   DynamicAutoDiffCostFunction<DynamicTwoParameterBlockFunctor>*
       actual_cost_function(
-      new DynamicAutoDiffCostFunction<DynamicTwoParameterBlockFunctor>(
-          new DynamicTwoParameterBlockFunctor));
+          new DynamicAutoDiffCostFunction<DynamicTwoParameterBlockFunctor>(
+              new DynamicTwoParameterBlockFunctor));
   actual_cost_function->AddParameterBlock(2);
   actual_cost_function->AddParameterBlock(2);
   actual_cost_function->SetNumResiduals(2);
diff --git a/internal/ceres/covariance.cc b/internal/ceres/covariance.cc
index 068cd9c..8e240ff 100644
--- a/internal/ceres/covariance.cc
+++ b/internal/ceres/covariance.cc
@@ -32,6 +32,7 @@
 
 #include <utility>
 #include <vector>
+
 #include "ceres/covariance_impl.h"
 #include "ceres/problem.h"
 #include "ceres/problem_impl.h"
@@ -46,19 +47,17 @@
   impl_.reset(new internal::CovarianceImpl(options));
 }
 
-Covariance::~Covariance() {
-}
+Covariance::~Covariance() {}
 
 bool Covariance::Compute(
     const vector<pair<const double*, const double*>>& covariance_blocks,
     Problem* problem) {
-  return impl_->Compute(covariance_blocks, problem->problem_impl_.get());
+  return impl_->Compute(covariance_blocks, problem->impl_.get());
 }
 
-bool Covariance::Compute(
-    const vector<const double*>& parameter_blocks,
-    Problem* problem) {
-  return impl_->Compute(parameter_blocks, problem->problem_impl_.get());
+bool Covariance::Compute(const vector<const double*>& parameter_blocks,
+                         Problem* problem) {
+  return impl_->Compute(parameter_blocks, problem->impl_.get());
 }
 
 bool Covariance::GetCovarianceBlock(const double* parameter_block1,
@@ -82,15 +81,15 @@
 
 bool Covariance::GetCovarianceMatrix(
     const vector<const double*>& parameter_blocks,
-    double* covariance_matrix) {
+    double* covariance_matrix) const {
   return impl_->GetCovarianceMatrixInTangentOrAmbientSpace(parameter_blocks,
                                                            true,  // ambient
                                                            covariance_matrix);
 }
 
 bool Covariance::GetCovarianceMatrixInTangentSpace(
-    const std::vector<const double *>& parameter_blocks,
-    double *covariance_matrix) {
+    const std::vector<const double*>& parameter_blocks,
+    double* covariance_matrix) const {
   return impl_->GetCovarianceMatrixInTangentOrAmbientSpace(parameter_blocks,
                                                            false,  // tangent
                                                            covariance_matrix);
diff --git a/internal/ceres/covariance_impl.cc b/internal/ceres/covariance_impl.cc
index d24f5c9..1f86707 100644
--- a/internal/ceres/covariance_impl.cc
+++ b/internal/ceres/covariance_impl.cc
@@ -39,10 +39,9 @@
 #include <utility>
 #include <vector>
 
+#include "Eigen/SVD"
 #include "Eigen/SparseCore"
 #include "Eigen/SparseQR"
-#include "Eigen/SVD"
-
 #include "ceres/compressed_col_sparse_matrix_utils.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/covariance.h"
@@ -61,25 +60,17 @@
 namespace ceres {
 namespace internal {
 
-using std::make_pair;
-using std::map;
-using std::pair;
-using std::sort;
 using std::swap;
-using std::vector;
 
-typedef vector<pair<const double*, const double*>> CovarianceBlocks;
+using CovarianceBlocks = std::vector<std::pair<const double*, const double*>>;
 
 CovarianceImpl::CovarianceImpl(const Covariance::Options& options)
-    : options_(options),
-      is_computed_(false),
-      is_valid_(false) {
+    : options_(options), is_computed_(false), is_valid_(false) {
 #ifdef CERES_NO_THREADS
   if (options_.num_threads > 1) {
-    LOG(WARNING)
-        << "No threading support is compiled into this binary; "
-        << "only options.num_threads = 1 is supported. Switching "
-        << "to single threaded mode.";
+    LOG(WARNING) << "No threading support is compiled into this binary; "
+                 << "only options.num_threads = 1 is supported. Switching "
+                 << "to single threaded mode.";
     options_.num_threads = 1;
   }
 #endif
@@ -88,16 +79,16 @@
   evaluate_options_.apply_loss_function = options_.apply_loss_function;
 }
 
-CovarianceImpl::~CovarianceImpl() {
-}
+CovarianceImpl::~CovarianceImpl() {}
 
-template <typename T> void CheckForDuplicates(vector<T> blocks) {
+template <typename T>
+void CheckForDuplicates(std::vector<T> blocks) {
   sort(blocks.begin(), blocks.end());
-  typename vector<T>::iterator it =
+  typename std::vector<T>::iterator it =
       std::adjacent_find(blocks.begin(), blocks.end());
   if (it != blocks.end()) {
     // In case there are duplicates, we search for their location.
-    map<T, vector<int>> blocks_map;
+    std::map<T, std::vector<int>> blocks_map;
     for (int i = 0; i < blocks.size(); ++i) {
       blocks_map[blocks[i]].push_back(i);
     }
@@ -122,7 +113,8 @@
 
 bool CovarianceImpl::Compute(const CovarianceBlocks& covariance_blocks,
                              ProblemImpl* problem) {
-  CheckForDuplicates<pair<const double*, const double*>>(covariance_blocks);
+  CheckForDuplicates<std::pair<const double*, const double*>>(
+      covariance_blocks);
   problem_ = problem;
   parameter_block_to_row_index_.clear();
   covariance_matrix_.reset(NULL);
@@ -132,14 +124,14 @@
   return is_valid_;
 }
 
-bool CovarianceImpl::Compute(const vector<const double*>& parameter_blocks,
+bool CovarianceImpl::Compute(const std::vector<const double*>& parameter_blocks,
                              ProblemImpl* problem) {
   CheckForDuplicates<const double*>(parameter_blocks);
   CovarianceBlocks covariance_blocks;
   for (int i = 0; i < parameter_blocks.size(); ++i) {
     for (int j = i; j < parameter_blocks.size(); ++j) {
-      covariance_blocks.push_back(make_pair(parameter_blocks[i],
-                                            parameter_blocks[j]));
+      covariance_blocks.push_back(
+          std::make_pair(parameter_blocks[i], parameter_blocks[j]));
     }
   }
 
@@ -162,13 +154,11 @@
   if (constant_parameter_blocks_.count(original_parameter_block1) > 0 ||
       constant_parameter_blocks_.count(original_parameter_block2) > 0) {
     const ProblemImpl::ParameterMap& parameter_map = problem_->parameter_map();
-    ParameterBlock* block1 =
-        FindOrDie(parameter_map,
-                  const_cast<double*>(original_parameter_block1));
+    ParameterBlock* block1 = FindOrDie(
+        parameter_map, const_cast<double*>(original_parameter_block1));
 
-    ParameterBlock* block2 =
-        FindOrDie(parameter_map,
-                  const_cast<double*>(original_parameter_block2));
+    ParameterBlock* block2 = FindOrDie(
+        parameter_map, const_cast<double*>(original_parameter_block2));
 
     const int block1_size = block1->Size();
     const int block2_size = block2->Size();
@@ -210,8 +200,7 @@
 
   if (offset == row_size) {
     LOG(ERROR) << "Unable to find covariance block for "
-               << original_parameter_block1 << " "
-               << original_parameter_block2;
+               << original_parameter_block1 << " " << original_parameter_block2;
     return false;
   }
 
@@ -227,9 +216,8 @@
   const int block2_size = block2->Size();
   const int block2_local_size = block2->LocalSize();
 
-  ConstMatrixRef cov(covariance_matrix_->values() + rows[row_begin],
-                     block1_size,
-                     row_size);
+  ConstMatrixRef cov(
+      covariance_matrix_->values() + rows[row_begin], block1_size, row_size);
 
   // Fast path when there are no local parameterizations or if the
   // user does not want it lifted to the ambient space.
@@ -237,8 +225,8 @@
       !lift_covariance_to_ambient_space) {
     if (transpose) {
       MatrixRef(covariance_block, block2_local_size, block1_local_size) =
-          cov.block(0, offset, block1_local_size,
-                    block2_local_size).transpose();
+          cov.block(0, offset, block1_local_size, block2_local_size)
+              .transpose();
     } else {
       MatrixRef(covariance_block, block1_local_size, block2_local_size) =
           cov.block(0, offset, block1_local_size, block2_local_size);
@@ -298,7 +286,7 @@
 }
 
 bool CovarianceImpl::GetCovarianceMatrixInTangentOrAmbientSpace(
-    const vector<const double*>& parameters,
+    const std::vector<const double*>& parameters,
     bool lift_covariance_to_ambient_space,
     double* covariance_matrix) const {
   CHECK(is_computed_)
@@ -310,8 +298,8 @@
   const ProblemImpl::ParameterMap& parameter_map = problem_->parameter_map();
   // For OpenMP compatibility we need to define these vectors in advance
   const int num_parameters = parameters.size();
-  vector<int> parameter_sizes;
-  vector<int> cum_parameter_size;
+  std::vector<int> parameter_sizes;
+  std::vector<int> cum_parameter_size;
   parameter_sizes.reserve(num_parameters);
   cum_parameter_size.resize(num_parameters + 1);
   cum_parameter_size[0] = 0;
@@ -324,7 +312,8 @@
       parameter_sizes.push_back(block->LocalSize());
     }
   }
-  std::partial_sum(parameter_sizes.begin(), parameter_sizes.end(),
+  std::partial_sum(parameter_sizes.begin(),
+                   parameter_sizes.end(),
                    cum_parameter_size.begin() + 1);
   const int max_covariance_block_size =
       *std::max_element(parameter_sizes.begin(), parameter_sizes.end());
@@ -343,65 +332,66 @@
   // i = 1:n, j = i:n.
   int iteration_count = (num_parameters * (num_parameters + 1)) / 2;
   problem_->context()->EnsureMinimumThreads(num_threads);
-  ParallelFor(
-      problem_->context(),
-      0,
-      iteration_count,
-      num_threads,
-      [&](int thread_id, int k) {
-        int i, j;
-        LinearIndexToUpperTriangularIndex(k, num_parameters, &i, &j);
+  ParallelFor(problem_->context(),
+              0,
+              iteration_count,
+              num_threads,
+              [&](int thread_id, int k) {
+                int i, j;
+                LinearIndexToUpperTriangularIndex(k, num_parameters, &i, &j);
 
-        int covariance_row_idx = cum_parameter_size[i];
-        int covariance_col_idx = cum_parameter_size[j];
-        int size_i = parameter_sizes[i];
-        int size_j = parameter_sizes[j];
-        double* covariance_block =
-            workspace.get() + thread_id * max_covariance_block_size *
-            max_covariance_block_size;
-        if (!GetCovarianceBlockInTangentOrAmbientSpace(
-                parameters[i], parameters[j],
-                lift_covariance_to_ambient_space, covariance_block)) {
-          success = false;
-        }
+                int covariance_row_idx = cum_parameter_size[i];
+                int covariance_col_idx = cum_parameter_size[j];
+                int size_i = parameter_sizes[i];
+                int size_j = parameter_sizes[j];
+                double* covariance_block =
+                    workspace.get() + thread_id * max_covariance_block_size *
+                                          max_covariance_block_size;
+                if (!GetCovarianceBlockInTangentOrAmbientSpace(
+                        parameters[i],
+                        parameters[j],
+                        lift_covariance_to_ambient_space,
+                        covariance_block)) {
+                  success = false;
+                }
 
-        covariance.block(covariance_row_idx, covariance_col_idx, size_i,
-                         size_j) = MatrixRef(covariance_block, size_i, size_j);
+                covariance.block(
+                    covariance_row_idx, covariance_col_idx, size_i, size_j) =
+                    MatrixRef(covariance_block, size_i, size_j);
 
-        if (i != j) {
-          covariance.block(covariance_col_idx, covariance_row_idx,
-                           size_j, size_i) =
-              MatrixRef(covariance_block, size_i, size_j).transpose();
-        }
-      });
+                if (i != j) {
+                  covariance.block(
+                      covariance_col_idx, covariance_row_idx, size_j, size_i) =
+                      MatrixRef(covariance_block, size_i, size_j).transpose();
+                }
+              });
   return success;
 }
 
 // Determine the sparsity pattern of the covariance matrix based on
 // the block pairs requested by the user.
 bool CovarianceImpl::ComputeCovarianceSparsity(
-    const CovarianceBlocks&  original_covariance_blocks,
-    ProblemImpl* problem) {
+    const CovarianceBlocks& original_covariance_blocks, ProblemImpl* problem) {
   EventLogger event_logger("CovarianceImpl::ComputeCovarianceSparsity");
 
   // Determine an ordering for the parameter block, by sorting the
   // parameter blocks by their pointers.
-  vector<double*> all_parameter_blocks;
+  std::vector<double*> all_parameter_blocks;
   problem->GetParameterBlocks(&all_parameter_blocks);
   const ProblemImpl::ParameterMap& parameter_map = problem->parameter_map();
   std::unordered_set<ParameterBlock*> parameter_blocks_in_use;
-  vector<ResidualBlock*> residual_blocks;
+  std::vector<ResidualBlock*> residual_blocks;
   problem->GetResidualBlocks(&residual_blocks);
 
   for (int i = 0; i < residual_blocks.size(); ++i) {
     ResidualBlock* residual_block = residual_blocks[i];
     parameter_blocks_in_use.insert(residual_block->parameter_blocks(),
                                    residual_block->parameter_blocks() +
-                                   residual_block->NumParameterBlocks());
+                                       residual_block->NumParameterBlocks());
   }
 
   constant_parameter_blocks_.clear();
-  vector<double*>& active_parameter_blocks =
+  std::vector<double*>& active_parameter_blocks =
       evaluate_options_.parameter_blocks;
   active_parameter_blocks.clear();
   for (int i = 0; i < all_parameter_blocks.size(); ++i) {
@@ -434,8 +424,8 @@
   // triangular part of the matrix.
   int num_nonzeros = 0;
   CovarianceBlocks covariance_blocks;
-  for (int i = 0; i <  original_covariance_blocks.size(); ++i) {
-    const pair<const double*, const double*>& block_pair =
+  for (int i = 0; i < original_covariance_blocks.size(); ++i) {
+    const std::pair<const double*, const double*>& block_pair =
         original_covariance_blocks[i];
     if (constant_parameter_blocks_.count(block_pair.first) > 0 ||
         constant_parameter_blocks_.count(block_pair.second) > 0) {
@@ -450,8 +440,8 @@
 
     // Make sure we are constructing a block upper triangular matrix.
     if (index1 > index2) {
-      covariance_blocks.push_back(make_pair(block_pair.second,
-                                            block_pair.first));
+      covariance_blocks.push_back(
+          std::make_pair(block_pair.second, block_pair.first));
     } else {
       covariance_blocks.push_back(block_pair);
     }
@@ -466,7 +456,7 @@
   // Sort the block pairs. As a consequence we get the covariance
   // blocks as they will occur in the CompressedRowSparseMatrix that
   // will store the covariance.
-  sort(covariance_blocks.begin(), covariance_blocks.end());
+  std::sort(covariance_blocks.begin(), covariance_blocks.end());
 
   // Fill the sparsity pattern of the covariance matrix.
   covariance_matrix_.reset(
@@ -486,10 +476,10 @@
   // values of the parameter blocks. Thus iterating over the keys of
   // parameter_block_to_row_index_ corresponds to iterating over the
   // rows of the covariance matrix in order.
-  int i = 0;  // index into covariance_blocks.
+  int i = 0;       // index into covariance_blocks.
   int cursor = 0;  // index into the covariance matrix.
   for (const auto& entry : parameter_block_to_row_index_) {
-    const double* row_block =  entry.first;
+    const double* row_block = entry.first;
     const int row_block_size = problem->ParameterBlockLocalSize(row_block);
     int row_begin = entry.second;
 
@@ -498,7 +488,7 @@
     int num_col_blocks = 0;
     int num_columns = 0;
     for (int j = i; j < covariance_blocks.size(); ++j, ++num_col_blocks) {
-      const pair<const double*, const double*>& block_pair =
+      const std::pair<const double*, const double*>& block_pair =
           covariance_blocks[j];
       if (block_pair.first != row_block) {
         break;
@@ -519,7 +509,7 @@
       }
     }
 
-    i+= num_col_blocks;
+    i += num_col_blocks;
   }
 
   rows[num_rows] = cursor;
@@ -580,9 +570,9 @@
   const int num_cols = jacobian.num_cols;
   const int num_nonzeros = jacobian.values.size();
 
-  vector<SuiteSparse_long> transpose_rows(num_cols + 1, 0);
-  vector<SuiteSparse_long> transpose_cols(num_nonzeros, 0);
-  vector<double> transpose_values(num_nonzeros, 0);
+  std::vector<SuiteSparse_long> transpose_rows(num_cols + 1, 0);
+  std::vector<SuiteSparse_long> transpose_cols(num_nonzeros, 0);
+  std::vector<double> transpose_values(num_nonzeros, 0);
 
   for (int idx = 0; idx < num_nonzeros; ++idx) {
     transpose_rows[jacobian.cols[idx] + 1] += 1;
@@ -602,7 +592,7 @@
     }
   }
 
-  for (int i = transpose_rows.size() - 1; i > 0 ; --i) {
+  for (int i = transpose_rows.size() - 1; i > 0; --i) {
     transpose_rows[i] = transpose_rows[i - 1];
   }
   transpose_rows[0] = 0;
@@ -642,16 +632,20 @@
   // more efficient, both in runtime as well as the quality of
   // ordering computed. So, it maybe worth doing that analysis
   // separately.
-  const SuiteSparse_long rank =
-      SuiteSparseQR<double>(SPQR_ORDERING_BESTAMD,
-                            SPQR_DEFAULT_TOL,
-                            cholmod_jacobian.ncol,
-                            &cholmod_jacobian,
-                            &R,
-                            &permutation,
-                            &cc);
+  const SuiteSparse_long rank = SuiteSparseQR<double>(SPQR_ORDERING_BESTAMD,
+                                                      SPQR_DEFAULT_TOL,
+                                                      cholmod_jacobian.ncol,
+                                                      &cholmod_jacobian,
+                                                      &R,
+                                                      &permutation,
+                                                      &cc);
   event_logger.AddEvent("Numeric Factorization");
-  CHECK(R != nullptr);
+  if (R == nullptr) {
+    LOG(ERROR) << "Something is wrong. SuiteSparseQR returned R = nullptr.";
+    free(permutation);
+    cholmod_l_finish(&cc);
+    return false;
+  }
 
   if (rank < cholmod_jacobian.ncol) {
     LOG(ERROR) << "Jacobian matrix is rank deficient. "
@@ -663,7 +657,7 @@
     return false;
   }
 
-  vector<int> inverse_permutation(num_cols);
+  std::vector<int> inverse_permutation(num_cols);
   if (permutation) {
     for (SuiteSparse_long i = 0; i < num_cols; ++i) {
       inverse_permutation[permutation[i]] = i;
@@ -692,19 +686,18 @@
 
   problem_->context()->EnsureMinimumThreads(num_threads);
   ParallelFor(
-      problem_->context(),
-      0,
-      num_cols,
-      num_threads,
-      [&](int thread_id, int r) {
+      problem_->context(), 0, num_cols, num_threads, [&](int thread_id, int r) {
         const int row_begin = rows[r];
         const int row_end = rows[r + 1];
         if (row_end != row_begin) {
           double* solution = workspace.get() + thread_id * num_cols;
           SolveRTRWithSparseRHS<SuiteSparse_long>(
-              num_cols, static_cast<SuiteSparse_long*>(R->i),
-              static_cast<SuiteSparse_long*>(R->p), static_cast<double*>(R->x),
-              inverse_permutation[r], solution);
+              num_cols,
+              static_cast<SuiteSparse_long*>(R->i),
+              static_cast<SuiteSparse_long*>(R->p),
+              static_cast<double*>(R->x),
+              inverse_permutation[r],
+              solution);
           for (int idx = row_begin; idx < row_end; ++idx) {
             const int c = cols[idx];
             values[idx] = solution[inverse_permutation[c]];
@@ -747,8 +740,8 @@
   }
   event_logger.AddEvent("ConvertToDenseMatrix");
 
-  Eigen::JacobiSVD<Matrix> svd(dense_jacobian,
-                               Eigen::ComputeThinU | Eigen::ComputeThinV);
+  Eigen::BDCSVD<Matrix> svd(dense_jacobian,
+                            Eigen::ComputeThinU | Eigen::ComputeThinV);
 
   event_logger.AddEvent("SingularValueDecomposition");
 
@@ -796,10 +789,9 @@
         1.0 / (singular_values[i] * singular_values[i]);
   }
 
-  Matrix dense_covariance =
-      svd.matrixV() *
-      inverse_squared_singular_values.asDiagonal() *
-      svd.matrixV().transpose();
+  Matrix dense_covariance = svd.matrixV() *
+                            inverse_squared_singular_values.asDiagonal() *
+                            svd.matrixV().transpose();
   event_logger.AddEvent("PseudoInverse");
 
   const int num_rows = covariance_matrix_->num_rows();
@@ -834,13 +826,16 @@
   // Convert the matrix to column major order as required by SparseQR.
   EigenSparseMatrix sparse_jacobian =
       Eigen::MappedSparseMatrix<double, Eigen::RowMajor>(
-          jacobian.num_rows, jacobian.num_cols,
+          jacobian.num_rows,
+          jacobian.num_cols,
           static_cast<int>(jacobian.values.size()),
-          jacobian.rows.data(), jacobian.cols.data(), jacobian.values.data());
+          jacobian.rows.data(),
+          jacobian.cols.data(),
+          jacobian.values.data());
   event_logger.AddEvent("ConvertToSparseMatrix");
 
-  Eigen::SparseQR<EigenSparseMatrix, Eigen::COLAMDOrdering<int>>
-      qr_solver(sparse_jacobian);
+  Eigen::SparseQR<EigenSparseMatrix, Eigen::COLAMDOrdering<int>> qr_solver(
+      sparse_jacobian);
   event_logger.AddEvent("QRDecomposition");
 
   if (qr_solver.info() != Eigen::Success) {
@@ -878,22 +873,17 @@
 
   problem_->context()->EnsureMinimumThreads(num_threads);
   ParallelFor(
-      problem_->context(),
-      0,
-      num_cols,
-      num_threads,
-      [&](int thread_id, int r) {
+      problem_->context(), 0, num_cols, num_threads, [&](int thread_id, int r) {
         const int row_begin = rows[r];
         const int row_end = rows[r + 1];
         if (row_end != row_begin) {
           double* solution = workspace.get() + thread_id * num_cols;
-          SolveRTRWithSparseRHS<int>(
-              num_cols,
-              qr_solver.matrixR().innerIndexPtr(),
-              qr_solver.matrixR().outerIndexPtr(),
-              &qr_solver.matrixR().data().value(0),
-              inverse_permutation.indices().coeff(r),
-              solution);
+          SolveRTRWithSparseRHS<int>(num_cols,
+                                     qr_solver.matrixR().innerIndexPtr(),
+                                     qr_solver.matrixR().outerIndexPtr(),
+                                     &qr_solver.matrixR().data().value(0),
+                                     inverse_permutation.indices().coeff(r),
+                                     solution);
 
           // Assign the values of the computed covariance using the
           // inverse permutation used in the QR factorization.
diff --git a/internal/ceres/covariance_impl.h b/internal/ceres/covariance_impl.h
index 065e43c..394a04b 100644
--- a/internal/ceres/covariance_impl.h
+++ b/internal/ceres/covariance_impl.h
@@ -36,7 +36,9 @@
 #include <set>
 #include <utility>
 #include <vector>
+
 #include "ceres/covariance.h"
+#include "ceres/internal/port.h"
 #include "ceres/problem_impl.h"
 #include "ceres/suitesparse.h"
 
@@ -45,19 +47,17 @@
 
 class CompressedRowSparseMatrix;
 
-class CovarianceImpl {
+class CERES_EXPORT_INTERNAL CovarianceImpl {
  public:
   explicit CovarianceImpl(const Covariance::Options& options);
   ~CovarianceImpl();
 
-  bool Compute(
-      const std::vector<std::pair<const double*,
-                                  const double*>>& covariance_blocks,
-      ProblemImpl* problem);
+  bool Compute(const std::vector<std::pair<const double*, const double*>>&
+                   covariance_blocks,
+               ProblemImpl* problem);
 
-  bool Compute(
-      const std::vector<const double*>& parameter_blocks,
-      ProblemImpl* problem);
+  bool Compute(const std::vector<const double*>& parameter_blocks,
+               ProblemImpl* problem);
 
   bool GetCovarianceBlockInTangentOrAmbientSpace(
       const double* parameter_block1,
@@ -68,11 +68,11 @@
   bool GetCovarianceMatrixInTangentOrAmbientSpace(
       const std::vector<const double*>& parameters,
       bool lift_covariance_to_ambient_space,
-      double *covariance_matrix) const;
+      double* covariance_matrix) const;
 
   bool ComputeCovarianceSparsity(
-      const std::vector<std::pair<const double*,
-                                  const double*>>& covariance_blocks,
+      const std::vector<std::pair<const double*, const double*>>&
+          covariance_blocks,
       ProblemImpl* problem);
 
   bool ComputeCovarianceValues();
diff --git a/internal/ceres/covariance_test.cc b/internal/ceres/covariance_test.cc
index dea0723..229173f 100644
--- a/internal/ceres/covariance_test.cc
+++ b/internal/ceres/covariance_test.cc
@@ -31,12 +31,13 @@
 #include "ceres/covariance.h"
 
 #include <algorithm>
-#include <cstdint>
 #include <cmath>
+#include <cstdint>
 #include <map>
 #include <memory>
 #include <utility>
 
+#include "ceres/autodiff_cost_function.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/cost_function.h"
 #include "ceres/covariance_impl.h"
@@ -53,7 +54,7 @@
 using std::pair;
 using std::vector;
 
-class UnaryCostFunction: public CostFunction {
+class UnaryCostFunction : public CostFunction {
  public:
   UnaryCostFunction(const int num_residuals,
                     const int32_t parameter_block_size,
@@ -63,9 +64,9 @@
     mutable_parameter_block_sizes()->push_back(parameter_block_size);
   }
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     for (int i = 0; i < num_residuals(); ++i) {
       residuals[i] = 1;
     }
@@ -85,8 +86,7 @@
   vector<double> jacobian_;
 };
 
-
-class BinaryCostFunction: public CostFunction {
+class BinaryCostFunction : public CostFunction {
  public:
   BinaryCostFunction(const int num_residuals,
                      const int32_t parameter_block1_size,
@@ -102,9 +102,9 @@
     mutable_parameter_block_sizes()->push_back(parameter_block2_size);
   }
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     for (int i = 0; i < num_residuals(); ++i) {
       residuals[i] = 2;
     }
@@ -134,22 +134,22 @@
  public:
   virtual ~PolynomialParameterization() {}
 
-  virtual bool Plus(const double* x,
-                    const double* delta,
-                    double* x_plus_delta) const {
+  bool Plus(const double* x,
+            const double* delta,
+            double* x_plus_delta) const final {
     x_plus_delta[0] = delta[0] * x[0];
     x_plus_delta[1] = delta[0] * x[1];
     return true;
   }
 
-  virtual bool ComputeJacobian(const double* x, double* jacobian) const {
+  bool ComputeJacobian(const double* x, double* jacobian) const final {
     jacobian[0] = x[0];
     jacobian[1] = x[1];
     return true;
   }
 
-  virtual int GlobalSize() const { return 2; }
-  virtual int LocalSize() const { return 1; }
+  int GlobalSize() const final { return 2; }
+  int LocalSize() const final { return 1; }
 };
 
 TEST(CovarianceImpl, ComputeCovarianceSparsity) {
@@ -192,6 +192,7 @@
   //  . . . . . . X X X X
   //  . . . . . . X X X X
 
+  // clang-format off
   int expected_rows[] = {0, 5, 10, 15, 18, 21, 24, 28, 32, 36, 40};
   int expected_cols[] = {0, 6, 7, 8, 9,
                          1, 2, 3, 4, 5,
@@ -203,7 +204,7 @@
                          6, 7, 8, 9,
                          6, 7, 8, 9,
                          6, 7, 8, 9};
-
+  // clang-format on
 
   vector<pair<const double*, const double*>> covariance_blocks;
   covariance_blocks.push_back(make_pair(block1, block1));
@@ -215,8 +216,8 @@
 
   Covariance::Options options;
   CovarianceImpl covariance_impl(options);
-  EXPECT_TRUE(covariance_impl
-              .ComputeCovarianceSparsity(covariance_blocks, &problem));
+  EXPECT_TRUE(
+      covariance_impl.ComputeCovarianceSparsity(covariance_blocks, &problem));
 
   const CompressedRowSparseMatrix* crsm = covariance_impl.covariance_matrix();
 
@@ -227,17 +228,13 @@
   const int* rows = crsm->rows();
   for (int r = 0; r < crsm->num_rows() + 1; ++r) {
     EXPECT_EQ(rows[r], expected_rows[r])
-        << r << " "
-        << rows[r] << " "
-        << expected_rows[r];
+        << r << " " << rows[r] << " " << expected_rows[r];
   }
 
   const int* cols = crsm->cols();
   for (int c = 0; c < crsm->num_nonzeros(); ++c) {
     EXPECT_EQ(cols[c], expected_cols[c])
-        << c << " "
-        << cols[c] << " "
-        << expected_cols[c];
+        << c << " " << cols[c] << " " << expected_cols[c];
   }
 }
 
@@ -279,6 +276,7 @@
   //  . . . X X X X
   //  . . . X X X X
 
+  // clang-format off
   int expected_rows[] = {0, 5, 7, 9, 13, 17, 21, 25};
   int expected_cols[] = {0, 3, 4, 5, 6,
                          1, 2,
@@ -287,6 +285,7 @@
                          3, 4, 5, 6,
                          3, 4, 5, 6,
                          3, 4, 5, 6};
+  // clang-format on
 
   vector<pair<const double*, const double*>> covariance_blocks;
   covariance_blocks.push_back(make_pair(block1, block1));
@@ -298,8 +297,8 @@
 
   Covariance::Options options;
   CovarianceImpl covariance_impl(options);
-  EXPECT_TRUE(covariance_impl
-              .ComputeCovarianceSparsity(covariance_blocks, &problem));
+  EXPECT_TRUE(
+      covariance_impl.ComputeCovarianceSparsity(covariance_blocks, &problem));
 
   const CompressedRowSparseMatrix* crsm = covariance_impl.covariance_matrix();
 
@@ -310,17 +309,13 @@
   const int* rows = crsm->rows();
   for (int r = 0; r < crsm->num_rows() + 1; ++r) {
     EXPECT_EQ(rows[r], expected_rows[r])
-        << r << " "
-        << rows[r] << " "
-        << expected_rows[r];
+        << r << " " << rows[r] << " " << expected_rows[r];
   }
 
   const int* cols = crsm->cols();
   for (int c = 0; c < crsm->num_nonzeros(); ++c) {
     EXPECT_EQ(cols[c], expected_cols[c])
-        << c << " "
-        << cols[c] << " "
-        << expected_cols[c];
+        << c << " " << cols[c] << " " << expected_cols[c];
   }
 }
 
@@ -360,6 +355,7 @@
   //  . . . X X X X
   //  . . . X X X X
 
+  // clang-format off
   int expected_rows[] = {0, 5, 7, 9, 13, 17, 21, 25};
   int expected_cols[] = {0, 3, 4, 5, 6,
                          1, 2,
@@ -368,6 +364,7 @@
                          3, 4, 5, 6,
                          3, 4, 5, 6,
                          3, 4, 5, 6};
+  // clang-format on
 
   vector<pair<const double*, const double*>> covariance_blocks;
   covariance_blocks.push_back(make_pair(block1, block1));
@@ -379,8 +376,8 @@
 
   Covariance::Options options;
   CovarianceImpl covariance_impl(options);
-  EXPECT_TRUE(covariance_impl
-              .ComputeCovarianceSparsity(covariance_blocks, &problem));
+  EXPECT_TRUE(
+      covariance_impl.ComputeCovarianceSparsity(covariance_blocks, &problem));
 
   const CompressedRowSparseMatrix* crsm = covariance_impl.covariance_matrix();
 
@@ -391,17 +388,13 @@
   const int* rows = crsm->rows();
   for (int r = 0; r < crsm->num_rows() + 1; ++r) {
     EXPECT_EQ(rows[r], expected_rows[r])
-        << r << " "
-        << rows[r] << " "
-        << expected_rows[r];
+        << r << " " << rows[r] << " " << expected_rows[r];
   }
 
   const int* cols = crsm->cols();
   for (int c = 0; c < crsm->num_nonzeros(); ++c) {
     EXPECT_EQ(cols[c], expected_cols[c])
-        << c << " "
-        << cols[c] << " "
-        << expected_cols[c];
+        << c << " " << cols[c] << " " << expected_cols[c];
   }
 }
 
@@ -409,7 +402,7 @@
  protected:
   typedef map<const double*, pair<int, int>> BoundsMap;
 
-  virtual void SetUp() {
+  void SetUp() override {
     double* x = parameters_;
     double* y = x + 2;
     double* z = y + 3;
@@ -422,40 +415,33 @@
     z[0] = 3;
 
     {
-      double jacobian[] = { 1.0, 0.0, 0.0, 1.0};
+      double jacobian[] = {1.0, 0.0, 0.0, 1.0};
       problem_.AddResidualBlock(new UnaryCostFunction(2, 2, jacobian), NULL, x);
     }
 
     {
-      double jacobian[] = { 2.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 2.0 };
+      double jacobian[] = {2.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 2.0};
       problem_.AddResidualBlock(new UnaryCostFunction(3, 3, jacobian), NULL, y);
     }
 
     {
       double jacobian = 5.0;
-      problem_.AddResidualBlock(new UnaryCostFunction(1, 1, &jacobian),
-                                NULL,
-                                z);
+      problem_.AddResidualBlock(
+          new UnaryCostFunction(1, 1, &jacobian), NULL, z);
     }
 
     {
-      double jacobian1[] = { 1.0, 2.0, 3.0 };
-      double jacobian2[] = { -5.0, -6.0 };
+      double jacobian1[] = {1.0, 2.0, 3.0};
+      double jacobian2[] = {-5.0, -6.0};
       problem_.AddResidualBlock(
-          new BinaryCostFunction(1, 3, 2, jacobian1, jacobian2),
-          NULL,
-          y,
-          x);
+          new BinaryCostFunction(1, 3, 2, jacobian1, jacobian2), NULL, y, x);
     }
 
     {
-      double jacobian1[] = {2.0 };
-      double jacobian2[] = { 3.0, -2.0 };
+      double jacobian1[] = {2.0};
+      double jacobian2[] = {3.0, -2.0};
       problem_.AddResidualBlock(
-          new BinaryCostFunction(1, 1, 2, jacobian1, jacobian2),
-          NULL,
-          z,
-          x);
+          new BinaryCostFunction(1, 1, 2, jacobian1, jacobian2), NULL, z, x);
     }
 
     all_covariance_blocks_.push_back(make_pair(x, x));
@@ -481,8 +467,7 @@
 
   // Computes covariance in tangent space.
   void ComputeAndCompareCovarianceBlocksInTangentSpace(
-                                         const Covariance::Options& options,
-                                         const double* expected_covariance) {
+      const Covariance::Options& options, const double* expected_covariance) {
     ComputeAndCompareCovarianceBlocksInTangentOrAmbientSpace(
         options,
         false,  // tangent
@@ -548,8 +533,9 @@
                                     bool lift_covariance_to_ambient_space,
                                     const Covariance& covariance,
                                     const double* expected_covariance) {
-    const BoundsMap& column_bounds = lift_covariance_to_ambient_space ?
-        column_bounds_ : local_column_bounds_;
+    const BoundsMap& column_bounds = lift_covariance_to_ambient_space
+                                         ? column_bounds_
+                                         : local_column_bounds_;
     const int row_begin = FindOrDie(column_bounds, block1).first;
     const int row_end = FindOrDie(column_bounds, block1).second;
     const int col_begin = FindOrDie(column_bounds, block2).first;
@@ -557,13 +543,10 @@
 
     Matrix actual(row_end - row_begin, col_end - col_begin);
     if (lift_covariance_to_ambient_space) {
-      EXPECT_TRUE(covariance.GetCovarianceBlock(block1,
-                                                block2,
-                                                actual.data()));
+      EXPECT_TRUE(covariance.GetCovarianceBlock(block1, block2, actual.data()));
     } else {
-      EXPECT_TRUE(covariance.GetCovarianceBlockInTangentSpace(block1,
-                                                              block2,
-                                                              actual.data()));
+      EXPECT_TRUE(covariance.GetCovarianceBlockInTangentSpace(
+          block1, block2, actual.data()));
     }
 
     int dof = 0;  // degrees of freedom = sum of LocalSize()s
@@ -571,22 +554,22 @@
       dof = std::max(dof, bound.second.second);
     }
     ConstMatrixRef expected(expected_covariance, dof, dof);
-    double diff_norm = (expected.block(row_begin,
-                                       col_begin,
-                                       row_end - row_begin,
-                                       col_end - col_begin) - actual).norm();
+    double diff_norm =
+        (expected.block(
+             row_begin, col_begin, row_end - row_begin, col_end - col_begin) -
+         actual)
+            .norm();
     diff_norm /= (row_end - row_begin) * (col_end - col_begin);
 
     const double kTolerance = 1e-5;
     EXPECT_NEAR(diff_norm, 0.0, kTolerance)
         << "rows: " << row_begin << " " << row_end << "  "
         << "cols: " << col_begin << " " << col_end << "  "
-        << "\n\n expected: \n " << expected.block(row_begin,
-                                                  col_begin,
-                                                  row_end - row_begin,
-                                                  col_end - col_begin)
-        << "\n\n actual: \n " << actual
-        << "\n\n full expected: \n" << expected;
+        << "\n\n expected: \n "
+        << expected.block(
+               row_begin, col_begin, row_end - row_begin, col_end - col_begin)
+        << "\n\n actual: \n " << actual << "\n\n full expected: \n"
+        << expected;
   }
 
   double parameters_[6];
@@ -596,7 +579,6 @@
   BoundsMap local_column_bounds_;
 };
 
-
 TEST_F(CovarianceTest, NormalBehavior) {
   // J
   //
@@ -619,6 +601,7 @@
   //    6  -4  0   0   0 29
 
   // inv(J'J) computed using octave.
+  // clang-format off
   double expected_covariance[] = {
      7.0747e-02,  -8.4923e-03,   1.6821e-02,   3.3643e-02,   5.0464e-02,  -1.5809e-02,  // NOLINT
     -8.4923e-03,   8.1352e-02,   2.4758e-02,   4.9517e-02,   7.4275e-02,   1.2978e-02,  // NOLINT
@@ -627,6 +610,7 @@
      5.0464e-02,   7.4275e-02,  -2.8906e-03,  -5.7813e-03,   2.4133e-01,  -1.9598e-04,  // NOLINT
     -1.5809e-02,   1.2978e-02,  -6.5325e-05,  -1.3065e-04,  -1.9598e-04,   3.9544e-02,  // NOLINT
   };
+  // clang-format on
 
   Covariance::Options options;
 
@@ -668,6 +652,7 @@
   //    6  -4  0   0   0 29
 
   // inv(J'J) computed using octave.
+  // clang-format off
   double expected_covariance[] = {
      7.0747e-02,  -8.4923e-03,   1.6821e-02,   3.3643e-02,   5.0464e-02,  -1.5809e-02,  // NOLINT
     -8.4923e-03,   8.1352e-02,   2.4758e-02,   4.9517e-02,   7.4275e-02,   1.2978e-02,  // NOLINT
@@ -676,6 +661,7 @@
      5.0464e-02,   7.4275e-02,  -2.8906e-03,  -5.7813e-03,   2.4133e-01,  -1.9598e-04,  // NOLINT
     -1.5809e-02,   1.2978e-02,  -6.5325e-05,  -1.3065e-04,  -1.9598e-04,   3.9544e-02,  // NOLINT
   };
+  // clang-format on
 
   Covariance::Options options;
   options.num_threads = 4;
@@ -720,6 +706,7 @@
   //  0  0  0  0  0 29
 
   // pinv(J'J) computed using octave.
+  // clang-format off
   double expected_covariance[] = {
               0,            0,            0,            0,            0,            0,  // NOLINT
               0,            0,            0,            0,            0,            0,  // NOLINT
@@ -727,6 +714,7 @@
               0,            0,     -0.02778,      0.19444,     -0.08333,     -0.00000,  // NOLINT
               0,            0,     -0.04167,     -0.08333,      0.12500,     -0.00000,  // NOLINT
               0,            0,     -0.00000,     -0.00000,     -0.00000,      0.03448   // NOLINT
+      // clang-format on
   };
 
   Covariance::Options options;
@@ -777,6 +765,7 @@
 
   // A * inv((J*A)'*(J*A)) * A'
   // Computed using octave.
+  // clang-format off
   double expected_covariance[] = {
     0.01766,   0.01766,   0.02158,   0.04316,   0.00000,  -0.00122,
     0.01766,   0.01766,   0.02158,   0.04316,   0.00000,  -0.00122,
@@ -785,6 +774,7 @@
     0.00000,   0.00000,   0.00000,   0.00000,   0.00000,   0.00000,
    -0.00122,  -0.00122,  -0.00149,  -0.00298,   0.00000,   0.03457
   };
+  // clang-format on
 
   Covariance::Options options;
 
@@ -839,12 +829,14 @@
 
   // inv((J*A)'*(J*A))
   // Computed using octave.
+  // clang-format off
   double expected_covariance[] = {
     0.01766,   0.02158,   0.04316,   -0.00122,
     0.02158,   0.24860,  -0.00281,   -0.00149,
     0.04316,  -0.00281,   0.24439,   -0.00298,
    -0.00122,  -0.00149,  -0.00298,    0.03457  // NOLINT
   };
+  // clang-format on
 
   Covariance::Options options;
 
@@ -902,12 +894,14 @@
 
   // pinv((J*A)'*(J*A))
   // Computed using octave.
+  // clang-format off
   double expected_covariance[] = {
     0.0, 0.0, 0.0, 0.0,
     0.0, 0.0, 0.0, 0.0,
     0.0, 0.0, 0.0, 0.0,
     0.0, 0.0, 0.0, 0.034482 // NOLINT
   };
+  // clang-format on
 
   Covariance::Options options;
 
@@ -950,6 +944,7 @@
   // 3.4142 is the smallest eigen value of J'J. The following matrix
   // was obtained by dropping the eigenvector corresponding to this
   // eigenvalue.
+  // clang-format off
   double expected_covariance[] = {
      5.4135e-02,  -3.5121e-02,   1.7257e-04,   3.4514e-04,   5.1771e-04,  -1.6076e-02,  // NOLINT
     -3.5121e-02,   3.8667e-02,  -1.9288e-03,  -3.8576e-03,  -5.7864e-03,   1.2549e-02,  // NOLINT
@@ -958,7 +953,7 @@
      5.1771e-04,  -5.7864e-03,  -5.2946e-02,  -1.0589e-01,   9.1162e-02,  -9.9988e-04,  // NOLINT
     -1.6076e-02,   1.2549e-02,  -3.3329e-04,  -6.6659e-04,  -9.9988e-04,   3.9539e-02   // NOLINT
   };
-
+  // clang-format on
 
   {
     Covariance::Options options;
@@ -1102,46 +1097,39 @@
 
 class RankDeficientCovarianceTest : public CovarianceTest {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     double* x = parameters_;
     double* y = x + 2;
     double* z = y + 3;
 
     {
-      double jacobian[] = { 1.0, 0.0, 0.0, 1.0};
+      double jacobian[] = {1.0, 0.0, 0.0, 1.0};
       problem_.AddResidualBlock(new UnaryCostFunction(2, 2, jacobian), NULL, x);
     }
 
     {
-      double jacobian[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+      double jacobian[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
       problem_.AddResidualBlock(new UnaryCostFunction(3, 3, jacobian), NULL, y);
     }
 
     {
       double jacobian = 5.0;
-      problem_.AddResidualBlock(new UnaryCostFunction(1, 1, &jacobian),
-                                NULL,
-                                z);
+      problem_.AddResidualBlock(
+          new UnaryCostFunction(1, 1, &jacobian), NULL, z);
     }
 
     {
-      double jacobian1[] = { 0.0, 0.0, 0.0 };
-      double jacobian2[] = { -5.0, -6.0 };
+      double jacobian1[] = {0.0, 0.0, 0.0};
+      double jacobian2[] = {-5.0, -6.0};
       problem_.AddResidualBlock(
-          new BinaryCostFunction(1, 3, 2, jacobian1, jacobian2),
-          NULL,
-          y,
-          x);
+          new BinaryCostFunction(1, 3, 2, jacobian1, jacobian2), NULL, y, x);
     }
 
     {
-      double jacobian1[] = {2.0 };
-      double jacobian2[] = { 3.0, -2.0 };
+      double jacobian1[] = {2.0};
+      double jacobian2[] = {3.0, -2.0};
       problem_.AddResidualBlock(
-          new BinaryCostFunction(1, 1, 2, jacobian1, jacobian2),
-          NULL,
-          z,
-          x);
+          new BinaryCostFunction(1, 1, 2, jacobian1, jacobian2), NULL, z, x);
     }
 
     all_covariance_blocks_.push_back(make_pair(x, x));
@@ -1179,6 +1167,7 @@
   //   6 -4  0  0  0 29
 
   // pinv(J'J) computed using octave.
+  // clang-format off
   double expected_covariance[] = {
      0.053998,  -0.033145,   0.000000,   0.000000,   0.000000,  -0.015744,
     -0.033145,   0.045067,   0.000000,   0.000000,   0.000000,   0.013074,
@@ -1187,6 +1176,7 @@
      0.000000,   0.000000,   0.000000,   0.000000,   0.000000,   0.000000,
     -0.015744,   0.013074,   0.000000,   0.000000,   0.000000,   0.039543
   };
+  // clang-format on
 
   Covariance::Options options;
   options.algorithm_type = DENSE_SVD;
@@ -1194,9 +1184,90 @@
   ComputeAndCompareCovarianceBlocks(options, expected_covariance);
 }
 
+struct LinearCostFunction {
+  template <typename T>
+  bool operator()(const T* x, const T* y, T* residual) const {
+    residual[0] = T(10.0) - *x;
+    residual[1] = T(5.0) - *y;
+    return true;
+  }
+  static CostFunction* Create() {
+    return new AutoDiffCostFunction<LinearCostFunction, 2, 1, 1>(
+        new LinearCostFunction);
+  }
+};
+
+TEST(Covariance, ZeroSizedLocalParameterizationGetCovariance) {
+  double x = 0.0;
+  double y = 1.0;
+  Problem problem;
+  problem.AddResidualBlock(LinearCostFunction::Create(), nullptr, &x, &y);
+  problem.SetParameterization(&y, new SubsetParameterization(1, {0}));
+  // J = [-1 0]
+  //     [ 0 0]
+  Covariance::Options options;
+  options.algorithm_type = DENSE_SVD;
+  Covariance covariance(options);
+  vector<pair<const double*, const double*>> covariance_blocks;
+  covariance_blocks.push_back(std::make_pair(&x, &x));
+  covariance_blocks.push_back(std::make_pair(&x, &y));
+  covariance_blocks.push_back(std::make_pair(&y, &x));
+  covariance_blocks.push_back(std::make_pair(&y, &y));
+  EXPECT_TRUE(covariance.Compute(covariance_blocks, &problem));
+
+  double value = -1;
+  covariance.GetCovarianceBlock(&x, &x, &value);
+  EXPECT_NEAR(value, 1.0, std::numeric_limits<double>::epsilon());
+
+  value = -1;
+  covariance.GetCovarianceBlock(&x, &y, &value);
+  EXPECT_NEAR(value, 0.0, std::numeric_limits<double>::epsilon());
+
+  value = -1;
+  covariance.GetCovarianceBlock(&y, &x, &value);
+  EXPECT_NEAR(value, 0.0, std::numeric_limits<double>::epsilon());
+
+  value = -1;
+  covariance.GetCovarianceBlock(&y, &y, &value);
+  EXPECT_NEAR(value, 0.0, std::numeric_limits<double>::epsilon());
+}
+
+TEST(Covariance, ZeroSizedLocalParameterizationGetCovarianceInTangentSpace) {
+  double x = 0.0;
+  double y = 1.0;
+  Problem problem;
+  problem.AddResidualBlock(LinearCostFunction::Create(), nullptr, &x, &y);
+  problem.SetParameterization(&y, new SubsetParameterization(1, {0}));
+  // J = [-1 0]
+  //     [ 0 0]
+  Covariance::Options options;
+  options.algorithm_type = DENSE_SVD;
+  Covariance covariance(options);
+  vector<pair<const double*, const double*>> covariance_blocks;
+  covariance_blocks.push_back(std::make_pair(&x, &x));
+  covariance_blocks.push_back(std::make_pair(&x, &y));
+  covariance_blocks.push_back(std::make_pair(&y, &x));
+  covariance_blocks.push_back(std::make_pair(&y, &y));
+  EXPECT_TRUE(covariance.Compute(covariance_blocks, &problem));
+
+  double value = -1;
+  covariance.GetCovarianceBlockInTangentSpace(&x, &x, &value);
+  EXPECT_NEAR(value, 1.0, std::numeric_limits<double>::epsilon());
+
+  value = -1;
+  // The following three calls, should not touch this value, since the
+  // tangent space is of size zero
+  covariance.GetCovarianceBlockInTangentSpace(&x, &y, &value);
+  EXPECT_EQ(value, -1);
+  covariance.GetCovarianceBlockInTangentSpace(&y, &x, &value);
+  EXPECT_EQ(value, -1);
+  covariance.GetCovarianceBlockInTangentSpace(&y, &y, &value);
+  EXPECT_EQ(value, -1);
+}
+
 class LargeScaleCovarianceTest : public ::testing::Test {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     num_parameter_blocks_ = 2000;
     parameter_block_size_ = 5;
     parameters_.reset(
@@ -1208,11 +1279,11 @@
       jacobian *= (i + 1);
 
       double* block_i = parameters_.get() + i * parameter_block_size_;
-      problem_.AddResidualBlock(new UnaryCostFunction(parameter_block_size_,
-                                                      parameter_block_size_,
-                                                      jacobian.data()),
-                                NULL,
-                                block_i);
+      problem_.AddResidualBlock(
+          new UnaryCostFunction(
+              parameter_block_size_, parameter_block_size_, jacobian.data()),
+          NULL,
+          block_i);
       for (int j = i; j < num_parameter_blocks_; ++j) {
         double* block_j = parameters_.get() + j * parameter_block_size_;
         all_covariance_blocks_.push_back(make_pair(block_i, block_j));
@@ -1244,8 +1315,10 @@
       covariance.GetCovarianceBlock(block_i, block_i, actual.data());
       EXPECT_NEAR((expected - actual).norm(), 0.0, kTolerance)
           << "block: " << i << ", " << i << "\n"
-          << "expected: \n" << expected << "\n"
-          << "actual: \n" << actual;
+          << "expected: \n"
+          << expected << "\n"
+          << "actual: \n"
+          << actual;
 
       expected.setZero();
       for (int j = i + 1; j < num_parameter_blocks_; ++j) {
@@ -1253,8 +1326,10 @@
         covariance.GetCovarianceBlock(block_i, block_j, actual.data());
         EXPECT_NEAR((expected - actual).norm(), 0.0, kTolerance)
             << "block: " << i << ", " << j << "\n"
-            << "expected: \n" << expected << "\n"
-            << "actual: \n" << actual;
+            << "expected: \n"
+            << expected << "\n"
+            << "actual: \n"
+            << actual;
       }
     }
   }
diff --git a/internal/ceres/cubic_interpolation_test.cc b/internal/ceres/cubic_interpolation_test.cc
index d68af22..3907d22 100644
--- a/internal/ceres/cubic_interpolation_test.cc
+++ b/internal/ceres/cubic_interpolation_test.cc
@@ -31,6 +31,7 @@
 #include "ceres/cubic_interpolation.h"
 
 #include <memory>
+
 #include "ceres/jet.h"
 #include "glog/logging.h"
 #include "gtest/gtest.h"
@@ -38,7 +39,7 @@
 namespace ceres {
 namespace internal {
 
-static const double kTolerance = 1e-12;
+static constexpr double kTolerance = 1e-12;
 
 TEST(Grid1D, OneDataDimension) {
   int x[] = {1, 2, 3};
@@ -65,9 +66,11 @@
 }
 
 TEST(Grid1D, TwoDataDimensionIntegerDataInterleaved) {
+  // clang-format off
   int x[] = {1, 5,
              2, 6,
              3, 7};
+  // clang-format on
 
   Grid1D<int, 2, true> grid(x, 0, 3);
   for (int i = 0; i < 3; ++i) {
@@ -78,10 +81,11 @@
   }
 }
 
-
 TEST(Grid1D, TwoDataDimensionIntegerDataStacked) {
+  // clang-format off
   int x[] = {1, 2, 3,
              5, 6, 7};
+  // clang-format on
 
   Grid1D<int, 2, false> grid(x, 0, 3);
   for (int i = 0; i < 3; ++i) {
@@ -93,8 +97,10 @@
 }
 
 TEST(Grid2D, OneDataDimensionRowMajor) {
+  // clang-format off
   int x[] = {1, 2, 3,
              2, 3, 4};
+  // clang-format on
   Grid2D<int, 1, true, true> grid(x, 0, 2, 0, 3);
   for (int r = 0; r < 2; ++r) {
     for (int c = 0; c < 3; ++c) {
@@ -106,8 +112,10 @@
 }
 
 TEST(Grid2D, OneDataDimensionRowMajorOutOfBounds) {
+  // clang-format off
   int x[] = {1, 2, 3,
              2, 3, 4};
+  // clang-format on
   Grid2D<int, 1, true, true> grid(x, 0, 2, 0, 3);
   double value;
   grid.GetValue(-1, -1, &value);
@@ -141,64 +149,72 @@
 }
 
 TEST(Grid2D, TwoDataDimensionRowMajorInterleaved) {
+  // clang-format off
   int x[] = {1, 4, 2, 8, 3, 12,
              2, 8, 3, 12, 4, 16};
+  // clang-format on
   Grid2D<int, 2, true, true> grid(x, 0, 2, 0, 3);
   for (int r = 0; r < 2; ++r) {
     for (int c = 0; c < 3; ++c) {
       double value[2];
       grid.GetValue(r, c, value);
       EXPECT_EQ(value[0], static_cast<double>(r + c + 1));
-      EXPECT_EQ(value[1], static_cast<double>(4 *(r + c + 1)));
+      EXPECT_EQ(value[1], static_cast<double>(4 * (r + c + 1)));
     }
   }
 }
 
 TEST(Grid2D, TwoDataDimensionRowMajorStacked) {
+  // clang-format off
   int x[] = {1,  2,  3,
              2,  3,  4,
              4,  8, 12,
              8, 12, 16};
+  // clang-format on
   Grid2D<int, 2, true, false> grid(x, 0, 2, 0, 3);
   for (int r = 0; r < 2; ++r) {
     for (int c = 0; c < 3; ++c) {
       double value[2];
       grid.GetValue(r, c, value);
       EXPECT_EQ(value[0], static_cast<double>(r + c + 1));
-      EXPECT_EQ(value[1], static_cast<double>(4 *(r + c + 1)));
+      EXPECT_EQ(value[1], static_cast<double>(4 * (r + c + 1)));
     }
   }
 }
 
 TEST(Grid2D, TwoDataDimensionColMajorInterleaved) {
+  // clang-format off
   int x[] = { 1,  4, 2,  8,
               2,  8, 3, 12,
               3, 12, 4, 16};
+  // clang-format on
   Grid2D<int, 2, false, true> grid(x, 0, 2, 0, 3);
   for (int r = 0; r < 2; ++r) {
     for (int c = 0; c < 3; ++c) {
       double value[2];
       grid.GetValue(r, c, value);
       EXPECT_EQ(value[0], static_cast<double>(r + c + 1));
-      EXPECT_EQ(value[1], static_cast<double>(4 *(r + c + 1)));
+      EXPECT_EQ(value[1], static_cast<double>(4 * (r + c + 1)));
     }
   }
 }
 
 TEST(Grid2D, TwoDataDimensionColMajorStacked) {
+  // clang-format off
   int x[] = {1,   2,
              2,   3,
              3,   4,
              4,   8,
              8,  12,
              12, 16};
+  // clang-format on
   Grid2D<int, 2, false, false> grid(x, 0, 2, 0, 3);
   for (int r = 0; r < 2; ++r) {
     for (int c = 0; c < 3; ++c) {
       double value[2];
       grid.GetValue(r, c, value);
       EXPECT_EQ(value[0], static_cast<double>(r + c + 1));
-      EXPECT_EQ(value[1], static_cast<double>(4 *(r + c + 1)));
+      EXPECT_EQ(value[1], static_cast<double>(4 * (r + c + 1)));
     }
   }
 }
@@ -214,8 +230,8 @@
 
     for (int x = 0; x < kNumSamples; ++x) {
       for (int dim = 0; dim < kDataDimension; ++dim) {
-      values_[x * kDataDimension + dim] =
-          (dim * dim  + 1) * (a  * x * x * x + b * x * x + c * x + d);
+        values_[x * kDataDimension + dim] =
+            (dim * dim + 1) * (a * x * x * x + b * x * x + c * x + d);
       }
     }
 
@@ -236,8 +252,9 @@
 
       for (int dim = 0; dim < kDataDimension; ++dim) {
         expected_f[dim] =
-            (dim * dim  + 1) * (a  * x * x * x + b * x * x + c * x + d);
-        expected_dfdx[dim] = (dim * dim + 1) * (3.0 * a * x * x + 2.0 * b * x + c);
+            (dim * dim + 1) * (a * x * x * x + b * x * x + c * x + d);
+        expected_dfdx[dim] =
+            (dim * dim + 1) * (3.0 * a * x * x + 2.0 * b * x + c);
       }
 
       interpolator.Evaluate(x, f, dfdx);
@@ -255,8 +272,8 @@
   }
 
  private:
-  static const int kNumSamples = 10;
-  static const int kNumTestSamples = 100;
+  static constexpr int kNumSamples = 10;
+  static constexpr int kNumTestSamples = 100;
   std::unique_ptr<double[]> values_;
 };
 
@@ -278,7 +295,6 @@
   RunPolynomialInterpolationTest<3>(0.0, 0.4, 1.0, 0.5);
 }
 
-
 TEST(CubicInterpolator, JetEvaluation) {
   const double values[] = {1.0, 2.0, 2.0, 5.0, 3.0, 9.0, 2.0, 7.0};
 
@@ -313,6 +329,10 @@
 
 class BiCubicInterpolatorTest : public ::testing::Test {
  public:
+  // This class needs to have an Eigen aligned operator new as it contains
+  // fixed-size Eigen types.
+  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+
   template <int kDataDimension>
   void RunPolynomialInterpolationTest(const Eigen::Matrix3d& coeff) {
     values_.reset(new double[kNumRows * kNumCols * kDataDimension]);
@@ -326,7 +346,8 @@
       }
     }
 
-    Grid2D<double, kDataDimension> grid(values_.get(), 0, kNumRows, 0, kNumCols);
+    Grid2D<double, kDataDimension> grid(
+        values_.get(), 0, kNumRows, 0, kNumCols);
     BiCubicInterpolator<Grid2D<double, kDataDimension>> interpolator(grid);
 
     for (int j = 0; j < kNumRowSamples; ++j) {
@@ -337,8 +358,10 @@
         interpolator.Evaluate(r, c, f, dfdr, dfdc);
         for (int dim = 0; dim < kDataDimension; ++dim) {
           EXPECT_NEAR(f[dim], (dim * dim + 1) * EvaluateF(r, c), kTolerance);
-          EXPECT_NEAR(dfdr[dim], (dim * dim + 1) * EvaluatedFdr(r, c), kTolerance);
-          EXPECT_NEAR(dfdc[dim], (dim * dim + 1) * EvaluatedFdc(r, c), kTolerance);
+          EXPECT_NEAR(
+              dfdr[dim], (dim * dim + 1) * EvaluatedFdr(r, c), kTolerance);
+          EXPECT_NEAR(
+              dfdc[dim], (dim * dim + 1) * EvaluatedFdc(r, c), kTolerance);
         }
       }
     }
@@ -369,12 +392,11 @@
     return (coeff_.row(1) + coeff_.col(1).transpose()) * x;
   }
 
-
   Eigen::Matrix3d coeff_;
-  static const int kNumRows = 10;
-  static const int kNumCols = 10;
-  static const int kNumRowSamples = 100;
-  static const int kNumColSamples = 100;
+  static constexpr int kNumRows = 10;
+  static constexpr int kNumCols = 10;
+  static constexpr int kNumRowSamples = 100;
+  static constexpr int kNumColSamples = 100;
   std::unique_ptr<double[]> values_;
 };
 
@@ -467,8 +489,10 @@
 }
 
 TEST(BiCubicInterpolator, JetEvaluation) {
+  // clang-format off
   const double values[] = {1.0, 5.0, 2.0, 10.0, 2.0, 6.0, 3.0, 5.0,
                            1.0, 2.0, 2.0,  2.0, 2.0, 2.0, 3.0, 1.0};
+  // clang-format on
 
   Grid2D<double, 2> grid(values, 0, 2, 0, 4);
   BiCubicInterpolator<Grid2D<double, 2>> interpolator(grid);
diff --git a/internal/ceres/cxsparse.cc b/internal/ceres/cxsparse.cc
index 5a02877..0167f98 100644
--- a/internal/ceres/cxsparse.cc
+++ b/internal/ceres/cxsparse.cc
@@ -33,13 +33,12 @@
 
 #ifndef CERES_NO_CXSPARSE
 
-#include "ceres/cxsparse.h"
-
 #include <string>
 #include <vector>
 
 #include "ceres/compressed_col_sparse_matrix_utils.h"
 #include "ceres/compressed_row_sparse_matrix.h"
+#include "ceres/cxsparse.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "glog/logging.h"
 
diff --git a/internal/ceres/cxsparse.h b/internal/ceres/cxsparse.h
index 28238d5..d3f76e0 100644
--- a/internal/ceres/cxsparse.h
+++ b/internal/ceres/cxsparse.h
@@ -145,12 +145,12 @@
 
   // SparseCholesky interface.
   virtual ~CXSparseCholesky();
-  virtual CompressedRowSparseMatrix::StorageType StorageType() const;
-  virtual LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
-                                                std::string* message);
-  virtual LinearSolverTerminationType Solve(const double* rhs,
-                                            double* solution,
-                                            std::string* message);
+  CompressedRowSparseMatrix::StorageType StorageType() const final;
+  LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
+                                        std::string* message) final;
+  LinearSolverTerminationType Solve(const double* rhs,
+                                    double* solution,
+                                    std::string* message) final;
 
  private:
   CXSparseCholesky(const OrderingType ordering_type);
@@ -166,7 +166,7 @@
 }  // namespace internal
 }  // namespace ceres
 
-#else   // CERES_NO_CXSPARSE
+#else
 
 typedef void cs_dis;
 
diff --git a/internal/ceres/dense_jacobian_writer.h b/internal/ceres/dense_jacobian_writer.h
index 1b04f38..28c60e2 100644
--- a/internal/ceres/dense_jacobian_writer.h
+++ b/internal/ceres/dense_jacobian_writer.h
@@ -35,21 +35,19 @@
 
 #include "ceres/casts.h"
 #include "ceres/dense_sparse_matrix.h"
+#include "ceres/internal/eigen.h"
 #include "ceres/parameter_block.h"
 #include "ceres/program.h"
 #include "ceres/residual_block.h"
 #include "ceres/scratch_evaluate_preparer.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
 
 class DenseJacobianWriter {
  public:
-  DenseJacobianWriter(Evaluator::Options /* ignored */,
-                      Program* program)
-    : program_(program) {
-  }
+  DenseJacobianWriter(Evaluator::Options /* ignored */, Program* program)
+      : program_(program) {}
 
   // JacobianWriter interface.
 
@@ -61,14 +59,13 @@
   }
 
   SparseMatrix* CreateJacobian() const {
-    return new DenseSparseMatrix(program_->NumResiduals(),
-                                 program_->NumEffectiveParameters(),
-                                 true);
+    return new DenseSparseMatrix(
+        program_->NumResiduals(), program_->NumEffectiveParameters(), true);
   }
 
   void Write(int residual_id,
              int residual_offset,
-             double **jacobians,
+             double** jacobians,
              SparseMatrix* jacobian) {
     DenseSparseMatrix* dense_jacobian = down_cast<DenseSparseMatrix*>(jacobian);
     const ResidualBlock* residual_block =
@@ -86,15 +83,14 @@
       }
 
       const int parameter_block_size = parameter_block->LocalSize();
-      ConstMatrixRef parameter_jacobian(jacobians[j],
-                                        num_residuals,
-                                        parameter_block_size);
+      ConstMatrixRef parameter_jacobian(
+          jacobians[j], num_residuals, parameter_block_size);
 
-      dense_jacobian->mutable_matrix().block(
-          residual_offset,
-          parameter_block->delta_offset(),
-          num_residuals,
-          parameter_block_size) = parameter_jacobian;
+      dense_jacobian->mutable_matrix().block(residual_offset,
+                                             parameter_block->delta_offset(),
+                                             num_residuals,
+                                             parameter_block_size) =
+          parameter_jacobian;
     }
   }
 
diff --git a/internal/ceres/dense_linear_solver_test.cc b/internal/ceres/dense_linear_solver_test.cc
index e2e02ca..3929a6f 100644
--- a/internal/ceres/dense_linear_solver_test.cc
+++ b/internal/ceres/dense_linear_solver_test.cc
@@ -29,6 +29,7 @@
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
 #include <memory>
+
 #include "ceres/casts.h"
 #include "ceres/context_impl.h"
 #include "ceres/linear_least_squares_problems.h"
@@ -45,7 +46,7 @@
     tuple<LinearSolverType, DenseLinearAlgebraLibraryType, bool, int>
         Param;
 
-std::string ParamInfoToString(testing::TestParamInfo<Param> info) {
+static std::string ParamInfoToString(testing::TestParamInfo<Param> info) {
   Param param = info.param;
   std::stringstream ss;
   ss << LinearSolverTypeToString(::testing::get<0>(param)) << "_"
@@ -107,11 +108,13 @@
   EXPECT_NEAR(residual, 0.0, 10 * std::numeric_limits<double>::epsilon());
 }
 
+namespace {
+
 // TODO(sameeragarwal): Should we move away from hard coded linear
 // least squares problem to randomly generated ones?
 #ifndef CERES_NO_LAPACK
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     DenseLinearSolver,
     DenseLinearSolverTest,
     ::testing::Combine(::testing::Values(DENSE_QR, DENSE_NORMAL_CHOLESKY),
@@ -122,7 +125,7 @@
 
 #else
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     DenseLinearSolver,
     DenseLinearSolverTest,
     ::testing::Combine(::testing::Values(DENSE_QR, DENSE_NORMAL_CHOLESKY),
@@ -132,6 +135,6 @@
     ParamInfoToString);
 
 #endif
-
+}  // namespace
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/dense_normal_cholesky_solver.cc b/internal/ceres/dense_normal_cholesky_solver.cc
index fe7d931..51c6390 100644
--- a/internal/ceres/dense_normal_cholesky_solver.cc
+++ b/internal/ceres/dense_normal_cholesky_solver.cc
@@ -132,13 +132,8 @@
   //
   // Note: This is a bit delicate, it assumes that the stride on this
   // matrix is the same as the number of rows.
-  BLAS::SymmetricRankKUpdate(A->num_rows(),
-                             num_cols,
-                             A->values(),
-                             true,
-                             1.0,
-                             0.0,
-                             lhs.data());
+  BLAS::SymmetricRankKUpdate(
+      A->num_rows(), num_cols, A->values(), true, 1.0, 0.0, lhs.data());
 
   if (per_solve_options.D != NULL) {
     // Undo the modifications to the matrix A.
@@ -153,13 +148,10 @@
 
   LinearSolver::Summary summary;
   summary.num_iterations = 1;
-  summary.termination_type =
-      LAPACK::SolveInPlaceUsingCholesky(num_cols,
-                                        lhs.data(),
-                                        x,
-                                        &summary.message);
+  summary.termination_type = LAPACK::SolveInPlaceUsingCholesky(
+      num_cols, lhs.data(), x, &summary.message);
   event_logger.AddEvent("Solve");
   return summary;
 }
-}   // namespace internal
-}   // namespace ceres
+}  // namespace internal
+}  // namespace ceres
diff --git a/internal/ceres/dense_normal_cholesky_solver.h b/internal/ceres/dense_normal_cholesky_solver.h
index c10bd7b..68ea611 100644
--- a/internal/ceres/dense_normal_cholesky_solver.h
+++ b/internal/ceres/dense_normal_cholesky_solver.h
@@ -73,16 +73,16 @@
 // library. This solver always returns a solution, it is the user's
 // responsibility to judge if the solution is good enough for their
 // purposes.
-class DenseNormalCholeskySolver: public DenseSparseMatrixSolver {
+class DenseNormalCholeskySolver : public DenseSparseMatrixSolver {
  public:
   explicit DenseNormalCholeskySolver(const LinearSolver::Options& options);
 
  private:
-  virtual LinearSolver::Summary SolveImpl(
+  LinearSolver::Summary SolveImpl(
       DenseSparseMatrix* A,
       const double* b,
       const LinearSolver::PerSolveOptions& per_solve_options,
-      double* x);
+      double* x) final;
 
   LinearSolver::Summary SolveUsingLAPACK(
       DenseSparseMatrix* A,
diff --git a/internal/ceres/dense_qr_solver.cc b/internal/ceres/dense_qr_solver.cc
index 161e9c6..44388f3 100644
--- a/internal/ceres/dense_qr_solver.cc
+++ b/internal/ceres/dense_qr_solver.cc
@@ -31,6 +31,7 @@
 #include "ceres/dense_qr_solver.h"
 
 #include <cstddef>
+
 #include "Eigen/Dense"
 #include "ceres/dense_sparse_matrix.h"
 #include "ceres/internal/eigen.h"
@@ -77,7 +78,7 @@
 
   // TODO(sameeragarwal): Since we are copying anyways, the diagonal
   // can be appended to the matrix instead of doing it on A.
-  lhs_ =  A->matrix();
+  lhs_ = A->matrix();
 
   if (per_solve_options.D != NULL) {
     // Undo the modifications to the matrix A.
@@ -164,5 +165,5 @@
   return summary;
 }
 
-}   // namespace internal
-}   // namespace ceres
+}  // namespace internal
+}  // namespace ceres
diff --git a/internal/ceres/dense_qr_solver.h b/internal/ceres/dense_qr_solver.h
index 2ec124f..980243b 100644
--- a/internal/ceres/dense_qr_solver.h
+++ b/internal/ceres/dense_qr_solver.h
@@ -32,8 +32,9 @@
 #ifndef CERES_INTERNAL_DENSE_QR_SOLVER_H_
 #define CERES_INTERNAL_DENSE_QR_SOLVER_H_
 
-#include "ceres/linear_solver.h"
 #include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
+#include "ceres/linear_solver.h"
 
 namespace ceres {
 namespace internal {
@@ -78,16 +79,16 @@
 // library. This solver always returns a solution, it is the user's
 // responsibility to judge if the solution is good enough for their
 // purposes.
-class DenseQRSolver: public DenseSparseMatrixSolver {
+class CERES_EXPORT_INTERNAL DenseQRSolver : public DenseSparseMatrixSolver {
  public:
   explicit DenseQRSolver(const LinearSolver::Options& options);
 
  private:
-  virtual LinearSolver::Summary SolveImpl(
+  LinearSolver::Summary SolveImpl(
       DenseSparseMatrix* A,
       const double* b,
       const LinearSolver::PerSolveOptions& per_solve_options,
-      double* x);
+      double* x) final;
 
   LinearSolver::Summary SolveUsingEigen(
       DenseSparseMatrix* A,
diff --git a/internal/ceres/dense_sparse_matrix.cc b/internal/ceres/dense_sparse_matrix.cc
index 72e0836..53207fe 100644
--- a/internal/ceres/dense_sparse_matrix.cc
+++ b/internal/ceres/dense_sparse_matrix.cc
@@ -31,17 +31,17 @@
 #include "ceres/dense_sparse_matrix.h"
 
 #include <algorithm>
-#include "ceres/triplet_sparse_matrix.h"
+
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/port.h"
+#include "ceres/triplet_sparse_matrix.h"
 #include "glog/logging.h"
 
 namespace ceres {
 namespace internal {
 
 DenseSparseMatrix::DenseSparseMatrix(int num_rows, int num_cols)
-    : has_diagonal_appended_(false),
-      has_diagonal_reserved_(false) {
+    : has_diagonal_appended_(false), has_diagonal_reserved_(false) {
   m_.resize(num_rows, num_cols);
   m_.setZero();
 }
@@ -49,11 +49,10 @@
 DenseSparseMatrix::DenseSparseMatrix(int num_rows,
                                      int num_cols,
                                      bool reserve_diagonal)
-    : has_diagonal_appended_(false),
-      has_diagonal_reserved_(reserve_diagonal) {
+    : has_diagonal_appended_(false), has_diagonal_reserved_(reserve_diagonal) {
   if (reserve_diagonal) {
     // Allocate enough space for the diagonal.
-    m_.resize(num_rows +  num_cols, num_cols);
+    m_.resize(num_rows + num_cols, num_cols);
   } else {
     m_.resize(num_rows, num_cols);
   }
@@ -64,9 +63,9 @@
     : m_(Eigen::MatrixXd::Zero(m.num_rows(), m.num_cols())),
       has_diagonal_appended_(false),
       has_diagonal_reserved_(false) {
-  const double *values = m.values();
-  const int *rows = m.rows();
-  const int *cols = m.cols();
+  const double* values = m.values();
+  const int* rows = m.rows();
+  const int* cols = m.cols();
   int num_nonzeros = m.num_nonzeros();
 
   for (int i = 0; i < num_nonzeros; ++i) {
@@ -75,14 +74,9 @@
 }
 
 DenseSparseMatrix::DenseSparseMatrix(const ColMajorMatrix& m)
-    : m_(m),
-      has_diagonal_appended_(false),
-      has_diagonal_reserved_(false) {
-}
+    : m_(m), has_diagonal_appended_(false), has_diagonal_reserved_(false) {}
 
-void DenseSparseMatrix::SetZero() {
-  m_.setZero();
-}
+void DenseSparseMatrix::SetZero() { m_.setZero(); }
 
 void DenseSparseMatrix::RightMultiply(const double* x, double* y) const {
   VectorRef(y, num_rows()) += matrix() * ConstVectorRef(x, num_cols());
@@ -105,7 +99,7 @@
   *dense_matrix = m_.block(0, 0, num_rows(), num_cols());
 }
 
-void DenseSparseMatrix::AppendDiagonal(double *d) {
+void DenseSparseMatrix::AppendDiagonal(double* d) {
   CHECK(!has_diagonal_appended_);
   if (!has_diagonal_reserved_) {
     ColMajorMatrix tmp = m_;
@@ -133,9 +127,7 @@
   return m_.rows();
 }
 
-int DenseSparseMatrix::num_cols() const {
-  return m_.cols();
-}
+int DenseSparseMatrix::num_cols() const { return m_.cols(); }
 
 int DenseSparseMatrix::num_nonzeros() const {
   if (has_diagonal_reserved_ && !has_diagonal_appended_) {
@@ -148,33 +140,30 @@
   return ConstColMajorMatrixRef(
       m_.data(),
       ((has_diagonal_reserved_ && !has_diagonal_appended_)
-       ? m_.rows() - m_.cols()
-       : m_.rows()),
+           ? m_.rows() - m_.cols()
+           : m_.rows()),
       m_.cols(),
       Eigen::Stride<Eigen::Dynamic, 1>(m_.rows(), 1));
 }
 
 ColMajorMatrixRef DenseSparseMatrix::mutable_matrix() {
-  return ColMajorMatrixRef(
-      m_.data(),
-      ((has_diagonal_reserved_ && !has_diagonal_appended_)
-       ? m_.rows() - m_.cols()
-       : m_.rows()),
-      m_.cols(),
-      Eigen::Stride<Eigen::Dynamic, 1>(m_.rows(), 1));
+  return ColMajorMatrixRef(m_.data(),
+                           ((has_diagonal_reserved_ && !has_diagonal_appended_)
+                                ? m_.rows() - m_.cols()
+                                : m_.rows()),
+                           m_.cols(),
+                           Eigen::Stride<Eigen::Dynamic, 1>(m_.rows(), 1));
 }
 
-
 void DenseSparseMatrix::ToTextFile(FILE* file) const {
   CHECK(file != nullptr);
-  const int active_rows =
-      (has_diagonal_reserved_ && !has_diagonal_appended_)
-      ? (m_.rows() - m_.cols())
-      : m_.rows();
+  const int active_rows = (has_diagonal_reserved_ && !has_diagonal_appended_)
+                              ? (m_.rows() - m_.cols())
+                              : m_.rows();
 
   for (int r = 0; r < active_rows; ++r) {
     for (int c = 0; c < m_.cols(); ++c) {
-      fprintf(file,  "% 10d % 10d %17f\n", r, c, m_(r, c));
+      fprintf(file, "% 10d % 10d %17f\n", r, c, m_(r, c));
     }
   }
 }
diff --git a/internal/ceres/dense_sparse_matrix.h b/internal/ceres/dense_sparse_matrix.h
index e5a5483..94064b3 100644
--- a/internal/ceres/dense_sparse_matrix.h
+++ b/internal/ceres/dense_sparse_matrix.h
@@ -34,6 +34,7 @@
 #define CERES_INTERNAL_DENSE_SPARSE_MATRIX_H_
 
 #include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
 #include "ceres/sparse_matrix.h"
 #include "ceres/types.h"
 
@@ -42,7 +43,7 @@
 
 class TripletSparseMatrix;
 
-class DenseSparseMatrix : public SparseMatrix {
+class CERES_EXPORT_INTERNAL DenseSparseMatrix : public SparseMatrix {
  public:
   // Build a matrix with the same content as the TripletSparseMatrix
   // m. This assumes that m does not have any repeated entries.
@@ -55,18 +56,18 @@
   virtual ~DenseSparseMatrix() {}
 
   // SparseMatrix interface.
-  virtual void SetZero();
-  virtual void RightMultiply(const double* x, double* y) const;
-  virtual void LeftMultiply(const double* x, double* y) const;
-  virtual void SquaredColumnNorm(double* x) const;
-  virtual void ScaleColumns(const double* scale);
-  virtual void ToDenseMatrix(Matrix* dense_matrix) const;
-  virtual void ToTextFile(FILE* file) const;
-  virtual int num_rows() const;
-  virtual int num_cols() const;
-  virtual int num_nonzeros() const;
-  virtual const double* values() const { return m_.data(); }
-  virtual double* mutable_values() { return m_.data(); }
+  void SetZero() final;
+  void RightMultiply(const double* x, double* y) const final;
+  void LeftMultiply(const double* x, double* y) const final;
+  void SquaredColumnNorm(double* x) const final;
+  void ScaleColumns(const double* scale) final;
+  void ToDenseMatrix(Matrix* dense_matrix) const final;
+  void ToTextFile(FILE* file) const final;
+  int num_rows() const final;
+  int num_cols() const final;
+  int num_nonzeros() const final;
+  const double* values() const final { return m_.data(); }
+  double* mutable_values() final { return m_.data(); }
 
   ConstColMajorMatrixRef matrix() const;
   ColMajorMatrixRef mutable_matrix();
@@ -92,7 +93,7 @@
   // Calling RemoveDiagonal removes the block. It is a fatal error to append a
   // diagonal to a matrix that already has an appended diagonal, and it is also
   // a fatal error to remove a diagonal from a matrix that has none.
-  void AppendDiagonal(double *d);
+  void AppendDiagonal(double* d);
   void RemoveDiagonal();
 
  private:
diff --git a/internal/ceres/dense_sparse_matrix_test.cc b/internal/ceres/dense_sparse_matrix_test.cc
index 4d52e81..2fa7216 100644
--- a/internal/ceres/dense_sparse_matrix_test.cc
+++ b/internal/ceres/dense_sparse_matrix_test.cc
@@ -35,17 +35,18 @@
 #include "ceres/dense_sparse_matrix.h"
 
 #include <memory>
+
 #include "ceres/casts.h"
+#include "ceres/internal/eigen.h"
 #include "ceres/linear_least_squares_problems.h"
 #include "ceres/triplet_sparse_matrix.h"
-#include "ceres/internal/eigen.h"
 #include "glog/logging.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
 
-void CompareMatrices(const SparseMatrix* a, const SparseMatrix* b) {
+static void CompareMatrices(const SparseMatrix* a, const SparseMatrix* b) {
   EXPECT_EQ(a->num_rows(), b->num_rows());
   EXPECT_EQ(a->num_cols(), b->num_cols());
 
@@ -67,8 +68,8 @@
 }
 
 class DenseSparseMatrixTest : public ::testing::Test {
- protected :
-  virtual void SetUp() {
+ protected:
+  void SetUp() final {
     std::unique_ptr<LinearLeastSquaresProblem> problem(
         CreateLinearLeastSquaresProblemFromId(1));
 
diff --git a/internal/ceres/detect_structure.cc b/internal/ceres/detect_structure.cc
index 959a0ee..4aac445 100644
--- a/internal/ceres/detect_structure.cc
+++ b/internal/ceres/detect_structure.cc
@@ -29,6 +29,7 @@
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
 #include "ceres/detect_structure.h"
+
 #include "ceres/internal/eigen.h"
 #include "glog/logging.h"
 
@@ -61,8 +62,7 @@
     } else if (*row_block_size != Eigen::Dynamic &&
                *row_block_size != row.block.size) {
       VLOG(2) << "Dynamic row block size because the block size changed from "
-              << *row_block_size << " to "
-              << row.block.size;
+              << *row_block_size << " to " << row.block.size;
       *row_block_size = Eigen::Dynamic;
     }
 
@@ -73,8 +73,7 @@
     } else if (*e_block_size != Eigen::Dynamic &&
                *e_block_size != bs.cols[e_block_id].size) {
       VLOG(2) << "Dynamic e block size because the block size changed from "
-              << *e_block_size << " to "
-              << bs.cols[e_block_id].size;
+              << *e_block_size << " to " << bs.cols[e_block_id].size;
       *e_block_size = Eigen::Dynamic;
     }
 
@@ -100,9 +99,11 @@
       }
     }
 
+    // clang-format off
     const bool is_everything_dynamic = (*row_block_size == Eigen::Dynamic &&
                                         *e_block_size == Eigen::Dynamic &&
                                         *f_block_size == Eigen::Dynamic);
+    // clang-format on
     if (is_everything_dynamic) {
       break;
     }
@@ -110,10 +111,12 @@
 
   CHECK_NE(*row_block_size, 0) << "No rows found";
   CHECK_NE(*e_block_size, 0) << "No e type blocks found";
+  // clang-format off
   VLOG(1) << "Schur complement static structure <"
           << *row_block_size << ","
           << *e_block_size << ","
           << *f_block_size << ">.";
+  // clang-format on
 }
 
 }  // namespace internal
diff --git a/internal/ceres/detect_structure.h b/internal/ceres/detect_structure.h
index 602581c..0624230 100644
--- a/internal/ceres/detect_structure.h
+++ b/internal/ceres/detect_structure.h
@@ -32,6 +32,7 @@
 #define CERES_INTERNAL_DETECT_STRUCTURE_H_
 
 #include "ceres/block_structure.h"
+#include "ceres/internal/port.h"
 
 namespace ceres {
 namespace internal {
@@ -55,11 +56,11 @@
 // Note: The structure of rows without any e-blocks has no effect on
 // the values returned by this function. It is entirely possible that
 // the f_block_size and row_blocks_size is not constant in such rows.
-void DetectStructure(const CompressedRowBlockStructure& bs,
-                     const int num_eliminate_blocks,
-                     int* row_block_size,
-                     int* e_block_size,
-                     int* f_block_size);
+void CERES_EXPORT DetectStructure(const CompressedRowBlockStructure& bs,
+                                  const int num_eliminate_blocks,
+                                  int* row_block_size,
+                                  int* e_block_size,
+                                  int* f_block_size);
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/detect_structure_test.cc b/internal/ceres/detect_structure_test.cc
index a701a19..8f9c5ed 100644
--- a/internal/ceres/detect_structure_test.cc
+++ b/internal/ceres/detect_structure_test.cc
@@ -28,11 +28,12 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/detect_structure.h"
+
 #include "Eigen/Core"
+#include "ceres/block_structure.h"
 #include "glog/logging.h"
 #include "gtest/gtest.h"
-#include "ceres/block_structure.h"
-#include "ceres/detect_structure.h"
 
 namespace ceres {
 namespace internal {
@@ -78,11 +79,8 @@
   int e_block_size = 0;
   int f_block_size = 0;
   const int num_eliminate_blocks = 1;
-  DetectStructure(bs,
-                  num_eliminate_blocks,
-                  &row_block_size,
-                  &e_block_size,
-                  &f_block_size);
+  DetectStructure(
+      bs, num_eliminate_blocks, &row_block_size, &e_block_size, &f_block_size);
 
   EXPECT_EQ(row_block_size, expected_row_block_size);
   EXPECT_EQ(e_block_size, expected_e_block_size);
@@ -130,11 +128,8 @@
   int e_block_size = 0;
   int f_block_size = 0;
   const int num_eliminate_blocks = 1;
-  DetectStructure(bs,
-                  num_eliminate_blocks,
-                  &row_block_size,
-                  &e_block_size,
-                  &f_block_size);
+  DetectStructure(
+      bs, num_eliminate_blocks, &row_block_size, &e_block_size, &f_block_size);
 
   EXPECT_EQ(row_block_size, expected_row_block_size);
   EXPECT_EQ(e_block_size, expected_e_block_size);
@@ -146,7 +141,6 @@
   const int expected_e_block_size = 3;
   const int expected_f_block_size = Eigen::Dynamic;
 
-
   CompressedRowBlockStructure bs;
 
   bs.cols.push_back(Block());
@@ -183,11 +177,8 @@
   int e_block_size = 0;
   int f_block_size = 0;
   const int num_eliminate_blocks = 1;
-  DetectStructure(bs,
-                  num_eliminate_blocks,
-                  &row_block_size,
-                  &e_block_size,
-                  &f_block_size);
+  DetectStructure(
+      bs, num_eliminate_blocks, &row_block_size, &e_block_size, &f_block_size);
 
   EXPECT_EQ(row_block_size, expected_row_block_size);
   EXPECT_EQ(e_block_size, expected_e_block_size);
@@ -235,11 +226,8 @@
   int e_block_size = 0;
   int f_block_size = 0;
   const int num_eliminate_blocks = 2;
-  DetectStructure(bs,
-                  num_eliminate_blocks,
-                  &row_block_size,
-                  &e_block_size,
-                  &f_block_size);
+  DetectStructure(
+      bs, num_eliminate_blocks, &row_block_size, &e_block_size, &f_block_size);
 
   EXPECT_EQ(row_block_size, expected_row_block_size);
   EXPECT_EQ(e_block_size, expected_e_block_size);
@@ -279,11 +267,8 @@
   int e_block_size = 0;
   int f_block_size = 0;
   const int num_eliminate_blocks = 1;
-  DetectStructure(bs,
-                  num_eliminate_blocks,
-                  &row_block_size,
-                  &e_block_size,
-                  &f_block_size);
+  DetectStructure(
+      bs, num_eliminate_blocks, &row_block_size, &e_block_size, &f_block_size);
 
   EXPECT_EQ(row_block_size, expected_row_block_size);
   EXPECT_EQ(e_block_size, expected_e_block_size);
diff --git a/internal/ceres/dogleg_strategy.cc b/internal/ceres/dogleg_strategy.cc
index ecc6b88..03ae22f 100644
--- a/internal/ceres/dogleg_strategy.cc
+++ b/internal/ceres/dogleg_strategy.cc
@@ -49,7 +49,7 @@
 namespace {
 const double kMaxMu = 1.0;
 const double kMinMu = 1e-8;
-}
+}  // namespace
 
 DoglegStrategy::DoglegStrategy(const TrustRegionStrategy::Options& options)
     : linear_solver_(options.linear_solver),
@@ -122,8 +122,8 @@
   //
   jacobian->SquaredColumnNorm(diagonal_.data());
   for (int i = 0; i < n; ++i) {
-    diagonal_[i] = std::min(std::max(diagonal_[i], min_diagonal_),
-                            max_diagonal_);
+    diagonal_[i] =
+        std::min(std::max(diagonal_[i], min_diagonal_), max_diagonal_);
   }
   diagonal_ = diagonal_.array().sqrt();
 
@@ -171,9 +171,8 @@
 // The gradient, the Gauss-Newton step, the Cauchy point,
 // and all calculations involving the Jacobian have to
 // be adjusted accordingly.
-void DoglegStrategy::ComputeGradient(
-    SparseMatrix* jacobian,
-    const double* residuals) {
+void DoglegStrategy::ComputeGradient(SparseMatrix* jacobian,
+                                     const double* residuals) {
   gradient_.setZero();
   jacobian->LeftMultiply(residuals, gradient_.data());
   gradient_.array() /= diagonal_.array();
@@ -187,8 +186,7 @@
   Jg.setZero();
   // The Jacobian is scaled implicitly by computing J * (D^-1 * (D^-1 * g))
   // instead of (J * D^-1) * (D^-1 * g).
-  Vector scaled_gradient =
-      (gradient_.array() / diagonal_.array()).matrix();
+  Vector scaled_gradient = (gradient_.array() / diagonal_.array()).matrix();
   jacobian->RightMultiply(scaled_gradient.data(), Jg.data());
   alpha_ = gradient_.squaredNorm() / Jg.squaredNorm();
 }
@@ -217,7 +215,7 @@
   // Case 2. The Cauchy point and the Gauss-Newton steps lie outside
   // the trust region. Rescale the Cauchy point to the trust region
   // and return.
-  if  (gradient_norm * alpha_ >= radius_) {
+  if (gradient_norm * alpha_ >= radius_) {
     dogleg_step = -(radius_ / gradient_norm) * gradient_;
     dogleg_step_norm_ = radius_;
     dogleg_step.array() /= diagonal_.array();
@@ -242,14 +240,12 @@
   //   = alpha * -gradient' gauss_newton_step - alpha^2 |gradient|^2
   const double c = b_dot_a - a_squared_norm;
   const double d = sqrt(c * c + b_minus_a_squared_norm *
-                        (pow(radius_, 2.0) - a_squared_norm));
+                                    (pow(radius_, 2.0) - a_squared_norm));
 
-  double beta =
-      (c <= 0)
-      ? (d - c) /  b_minus_a_squared_norm
-      : (radius_ * radius_ - a_squared_norm) / (d + c);
-  dogleg_step = (-alpha_ * (1.0 - beta)) * gradient_
-      + beta * gauss_newton_step_;
+  double beta = (c <= 0) ? (d - c) / b_minus_a_squared_norm
+                         : (radius_ * radius_ - a_squared_norm) / (d + c);
+  dogleg_step =
+      (-alpha_ * (1.0 - beta)) * gradient_ + beta * gauss_newton_step_;
   dogleg_step_norm_ = dogleg_step.norm();
   dogleg_step.array() /= diagonal_.array();
   VLOG(3) << "Dogleg step size: " << dogleg_step_norm_
@@ -345,13 +341,13 @@
   // correctly determined.
   const double kCosineThreshold = 0.99;
   const Vector2d grad_minimum = subspace_B_ * minimum + subspace_g_;
-  const double cosine_angle = -minimum.dot(grad_minimum) /
-      (minimum.norm() * grad_minimum.norm());
+  const double cosine_angle =
+      -minimum.dot(grad_minimum) / (minimum.norm() * grad_minimum.norm());
   if (cosine_angle < kCosineThreshold) {
     LOG(WARNING) << "First order optimality seems to be violated "
                  << "in the subspace method!\n"
-                 << "Cosine of angle between x and B x + g is "
-                 << cosine_angle << ".\n"
+                 << "Cosine of angle between x and B x + g is " << cosine_angle
+                 << ".\n"
                  << "Taking a regular dogleg step instead.\n"
                  << "Please consider filing a bug report if this "
                  << "happens frequently or consistently.\n";
@@ -423,15 +419,17 @@
   const double trB = subspace_B_.trace();
   const double r2 = radius_ * radius_;
   Matrix2d B_adj;
+  // clang-format off
   B_adj <<  subspace_B_(1, 1) , -subspace_B_(0, 1),
-            -subspace_B_(1, 0) ,  subspace_B_(0, 0);
+           -subspace_B_(1, 0) ,  subspace_B_(0, 0);
+  // clang-format on
 
   Vector polynomial(5);
   polynomial(0) = r2;
   polynomial(1) = 2.0 * r2 * trB;
   polynomial(2) = r2 * (trB * trB + 2.0 * detB) - subspace_g_.squaredNorm();
-  polynomial(3) = -2.0 * (subspace_g_.transpose() * B_adj * subspace_g_
-      - r2 * detB * trB);
+  polynomial(3) =
+      -2.0 * (subspace_g_.transpose() * B_adj * subspace_g_ - r2 * detB * trB);
   polynomial(4) = r2 * detB * detB - (B_adj * subspace_g_).squaredNorm();
 
   return polynomial;
@@ -565,10 +563,8 @@
     // of Jx = -r and later set x = -y to avoid having to modify
     // either jacobian or residuals.
     InvalidateArray(n, gauss_newton_step_.data());
-    linear_solver_summary = linear_solver_->Solve(jacobian,
-                                                  residuals,
-                                                  solve_options,
-                                                  gauss_newton_step_.data());
+    linear_solver_summary = linear_solver_->Solve(
+        jacobian, residuals, solve_options, gauss_newton_step_.data());
 
     if (per_solve_options.dump_format_type == CONSOLE ||
         (per_solve_options.dump_format_type != CONSOLE &&
@@ -641,9 +637,7 @@
   reuse_ = false;
 }
 
-double DoglegStrategy::Radius() const {
-  return radius_;
-}
+double DoglegStrategy::Radius() const { return radius_; }
 
 bool DoglegStrategy::ComputeSubspaceModel(SparseMatrix* jacobian) {
   // Compute an orthogonal basis for the subspace using QR decomposition.
@@ -701,8 +695,8 @@
 
   subspace_g_ = subspace_basis_.transpose() * gradient_;
 
-  Eigen::Matrix<double, 2, Eigen::Dynamic, Eigen::RowMajor>
-      Jb(2, jacobian->num_rows());
+  Eigen::Matrix<double, 2, Eigen::Dynamic, Eigen::RowMajor> Jb(
+      2, jacobian->num_rows());
   Jb.setZero();
 
   Vector tmp;
diff --git a/internal/ceres/dogleg_strategy.h b/internal/ceres/dogleg_strategy.h
index 11a3bb0..cc3778e 100644
--- a/internal/ceres/dogleg_strategy.h
+++ b/internal/ceres/dogleg_strategy.h
@@ -31,6 +31,7 @@
 #ifndef CERES_INTERNAL_DOGLEG_STRATEGY_H_
 #define CERES_INTERNAL_DOGLEG_STRATEGY_H_
 
+#include "ceres/internal/port.h"
 #include "ceres/linear_solver.h"
 #include "ceres/trust_region_strategy.h"
 
@@ -52,21 +53,20 @@
 // DoglegStrategy follows the approach by Shultz, Schnabel, Byrd.
 // This finds the exact optimum over the two-dimensional subspace
 // spanned by the two Dogleg vectors.
-class DoglegStrategy : public TrustRegionStrategy {
+class CERES_EXPORT_INTERNAL DoglegStrategy : public TrustRegionStrategy {
  public:
   explicit DoglegStrategy(const TrustRegionStrategy::Options& options);
   virtual ~DoglegStrategy() {}
 
   // TrustRegionStrategy interface
-  virtual Summary ComputeStep(const PerSolveOptions& per_solve_options,
-                              SparseMatrix* jacobian,
-                              const double* residuals,
-                              double* step);
-  virtual void StepAccepted(double step_quality);
-  virtual void StepRejected(double step_quality);
-  virtual void StepIsInvalid();
-
-  virtual double Radius() const;
+  Summary ComputeStep(const PerSolveOptions& per_solve_options,
+                      SparseMatrix* jacobian,
+                      const double* residuals,
+                      double* step) final;
+  void StepAccepted(double step_quality) final;
+  void StepRejected(double step_quality) final;
+  void StepIsInvalid();
+  double Radius() const final;
 
   // These functions are predominantly for testing.
   Vector gradient() const { return gradient_; }
diff --git a/internal/ceres/dogleg_strategy_test.cc b/internal/ceres/dogleg_strategy_test.cc
index c435be6..0c20f25 100644
--- a/internal/ceres/dogleg_strategy_test.cc
+++ b/internal/ceres/dogleg_strategy_test.cc
@@ -28,11 +28,13 @@
 //
 // Author: moll.markus@arcor.de (Markus Moll)
 
+#include "ceres/dogleg_strategy.h"
+
 #include <limits>
 #include <memory>
-#include "ceres/internal/eigen.h"
+
 #include "ceres/dense_qr_solver.h"
-#include "ceres/dogleg_strategy.h"
+#include "ceres/internal/eigen.h"
 #include "ceres/linear_solver.h"
 #include "ceres/trust_region_strategy.h"
 #include "glog/logging.h"
@@ -60,15 +62,17 @@
 // from the origin.
 class DoglegStrategyFixtureEllipse : public Fixture {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     Matrix basis(6, 6);
     // The following lines exceed 80 characters for better readability.
+    // clang-format off
     basis << -0.1046920933796121, -0.7449367449921986, -0.4190744502875876, -0.4480450716142566,  0.2375351607929440, -0.0363053418882862,  // NOLINT
               0.4064975684355914,  0.2681113508511354, -0.7463625494601520, -0.0803264850508117, -0.4463149623021321,  0.0130224954867195,  // NOLINT
              -0.5514387729089798,  0.1026621026168657, -0.5008316122125011,  0.5738122212666414,  0.2974664724007106,  0.1296020877535158,  // NOLINT
               0.5037835370947156,  0.2668479925183712, -0.1051754618492798, -0.0272739396578799,  0.7947481647088278, -0.1776623363955670,  // NOLINT
              -0.4005458426625444,  0.2939330589634109, -0.0682629380550051, -0.2895448882503687, -0.0457239396341685, -0.8139899477847840,  // NOLINT
              -0.3247764582762654,  0.4528151365941945, -0.0276683863102816, -0.6155994592510784,  0.1489240599972848,  0.5362574892189350;  // NOLINT
+    // clang-format on
 
     Vector Ddiag(6);
     Ddiag << 1.0, 2.0, 4.0, 8.0, 16.0, 32.0;
@@ -98,7 +102,7 @@
 // The gradient at the origin points towards the global minimum.
 class DoglegStrategyFixtureValley : public Fixture {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     Vector Ddiag(6);
     Ddiag << 1.0, 2.0, 4.0, 8.0, 16.0, 32.0;
 
@@ -139,10 +143,8 @@
   DoglegStrategy strategy(options_);
   TrustRegionStrategy::PerSolveOptions pso;
 
-  TrustRegionStrategy::Summary summary = strategy.ComputeStep(pso,
-                                                              jacobian_.get(),
-                                                              residual_.data(),
-                                                              x_.data());
+  TrustRegionStrategy::Summary summary =
+      strategy.ComputeStep(pso, jacobian_.get(), residual_.data(), x_.data());
 
   EXPECT_NE(summary.termination_type, LINEAR_SOLVER_FAILURE);
   EXPECT_LE(x_.norm(), options_.initial_radius * (1.0 + 4.0 * kEpsilon));
@@ -159,10 +161,8 @@
   DoglegStrategy strategy(options_);
   TrustRegionStrategy::PerSolveOptions pso;
 
-  TrustRegionStrategy::Summary summary = strategy.ComputeStep(pso,
-                                                              jacobian_.get(),
-                                                              residual_.data(),
-                                                              x_.data());
+  TrustRegionStrategy::Summary summary =
+      strategy.ComputeStep(pso, jacobian_.get(), residual_.data(), x_.data());
 
   EXPECT_NE(summary.termination_type, LINEAR_SOLVER_FAILURE);
   EXPECT_LE(x_.norm(), options_.initial_radius * (1.0 + 4.0 * kEpsilon));
@@ -179,10 +179,8 @@
   DoglegStrategy strategy(options_);
   TrustRegionStrategy::PerSolveOptions pso;
 
-  TrustRegionStrategy::Summary summary = strategy.ComputeStep(pso,
-                                                              jacobian_.get(),
-                                                              residual_.data(),
-                                                              x_.data());
+  TrustRegionStrategy::Summary summary =
+      strategy.ComputeStep(pso, jacobian_.get(), residual_.data(), x_.data());
 
   EXPECT_NE(summary.termination_type, LINEAR_SOLVER_FAILURE);
   EXPECT_NEAR(x_(0), 1.0, kToleranceLoose);
@@ -216,15 +214,13 @@
 
   // Check if the gradient projects onto itself.
   const Vector gradient = strategy.gradient();
-  EXPECT_NEAR((gradient - basis*(basis.transpose()*gradient)).norm(),
+  EXPECT_NEAR((gradient - basis * (basis.transpose() * gradient)).norm(),
               0.0,
               kTolerance);
 
   // Check if the Gauss-Newton point projects onto itself.
   const Vector gn = strategy.gauss_newton_step();
-  EXPECT_NEAR((gn - basis*(basis.transpose()*gn)).norm(),
-              0.0,
-              kTolerance);
+  EXPECT_NEAR((gn - basis * (basis.transpose() * gn)).norm(), 0.0, kTolerance);
 }
 
 // Test if the step is correct if the gradient and the Gauss-Newton step point
@@ -241,10 +237,8 @@
   DoglegStrategy strategy(options_);
   TrustRegionStrategy::PerSolveOptions pso;
 
-  TrustRegionStrategy::Summary summary = strategy.ComputeStep(pso,
-                                                              jacobian_.get(),
-                                                              residual_.data(),
-                                                              x_.data());
+  TrustRegionStrategy::Summary summary =
+      strategy.ComputeStep(pso, jacobian_.get(), residual_.data(), x_.data());
 
   EXPECT_NE(summary.termination_type, LINEAR_SOLVER_FAILURE);
   EXPECT_NEAR(x_(0), 0.0, kToleranceLoose);
@@ -269,10 +263,8 @@
   DoglegStrategy strategy(options_);
   TrustRegionStrategy::PerSolveOptions pso;
 
-  TrustRegionStrategy::Summary summary = strategy.ComputeStep(pso,
-                                                              jacobian_.get(),
-                                                              residual_.data(),
-                                                              x_.data());
+  TrustRegionStrategy::Summary summary =
+      strategy.ComputeStep(pso, jacobian_.get(), residual_.data(), x_.data());
 
   EXPECT_NE(summary.termination_type, LINEAR_SOLVER_FAILURE);
   EXPECT_NEAR(x_(0), 0.0, kToleranceLoose);
diff --git a/internal/ceres/dynamic_autodiff_cost_function_test.cc b/internal/ceres/dynamic_autodiff_cost_function_test.cc
index 29f8d10..55d3fe1 100644
--- a/internal/ceres/dynamic_autodiff_cost_function_test.cc
+++ b/internal/ceres/dynamic_autodiff_cost_function_test.cc
@@ -30,10 +30,11 @@
 //         mierle@gmail.com (Keir Mierle)
 //         sameeragarwal@google.com (Sameer Agarwal)
 
-#include <cstddef>
-
-#include <memory>
 #include "ceres/dynamic_autodiff_cost_function.h"
+
+#include <cstddef>
+#include <memory>
+
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -87,9 +88,8 @@
   vector<double*> parameter_blocks(2);
   parameter_blocks[0] = &param_block_0[0];
   parameter_blocks[1] = &param_block_1[0];
-  EXPECT_TRUE(cost_function.Evaluate(&parameter_blocks[0],
-                                     residuals.data(),
-                                     NULL));
+  EXPECT_TRUE(
+      cost_function.Evaluate(&parameter_blocks[0], residuals.data(), NULL));
   for (int r = 0; r < 10; ++r) {
     EXPECT_EQ(1.0 * r, residuals.at(r * 2));
     EXPECT_EQ(-1.0 * r, residuals.at(r * 2 + 1));
@@ -127,9 +127,8 @@
   jacobian.push_back(jacobian_vect[1].data());
 
   // Test jacobian computation.
-  EXPECT_TRUE(cost_function.Evaluate(parameter_blocks.data(),
-                                     residuals.data(),
-                                     jacobian.data()));
+  EXPECT_TRUE(cost_function.Evaluate(
+      parameter_blocks.data(), residuals.data(), jacobian.data()));
 
   for (int r = 0; r < 10; ++r) {
     EXPECT_EQ(-1.0 * r, residuals.at(r * 2));
@@ -138,11 +137,11 @@
   EXPECT_EQ(420, residuals.at(20));
   for (int p = 0; p < 10; ++p) {
     // Check "A" Jacobian.
-    EXPECT_EQ(-1.0, jacobian_vect[0][2*p * 10 + p]);
+    EXPECT_EQ(-1.0, jacobian_vect[0][2 * p * 10 + p]);
     // Check "B" Jacobian.
-    EXPECT_EQ(+1.0, jacobian_vect[0][(2*p+1) * 10 + p]);
-    jacobian_vect[0][2*p * 10 + p] = 0.0;
-    jacobian_vect[0][(2*p+1) * 10 + p] = 0.0;
+    EXPECT_EQ(+1.0, jacobian_vect[0][(2 * p + 1) * 10 + p]);
+    jacobian_vect[0][2 * p * 10 + p] = 0.0;
+    jacobian_vect[0][(2 * p + 1) * 10 + p] = 0.0;
   }
 
   // Check "C" Jacobian for first parameter block.
@@ -194,9 +193,8 @@
   jacobian.push_back(jacobian_vect[1].data());
 
   // Test jacobian computation.
-  EXPECT_TRUE(cost_function.Evaluate(parameter_blocks.data(),
-                                     residuals.data(),
-                                     jacobian.data()));
+  EXPECT_TRUE(cost_function.Evaluate(
+      parameter_blocks.data(), residuals.data(), jacobian.data()));
 
   for (int r = 0; r < 10; ++r) {
     EXPECT_EQ(-1.0 * r, residuals.at(r * 2));
@@ -214,7 +212,8 @@
   }
 }
 
-TEST(DynamicAutodiffCostFunctionTest, JacobianWithSecondParameterBlockConstant) {  // NOLINT
+TEST(DynamicAutodiffCostFunctionTest,
+     JacobianWithSecondParameterBlockConstant) {  // NOLINT
   // Test the residual counting.
   vector<double> param_block_0(10, 0.0);
   for (int i = 0; i < 10; ++i) {
@@ -244,9 +243,8 @@
   jacobian.push_back(NULL);
 
   // Test jacobian computation.
-  EXPECT_TRUE(cost_function.Evaluate(parameter_blocks.data(),
-                                     residuals.data(),
-                                     jacobian.data()));
+  EXPECT_TRUE(cost_function.Evaluate(
+      parameter_blocks.data(), residuals.data(), jacobian.data()));
 
   for (int r = 0; r < 10; ++r) {
     EXPECT_EQ(-1.0 * r, residuals.at(r * 2));
@@ -255,11 +253,11 @@
   EXPECT_EQ(420, residuals.at(20));
   for (int p = 0; p < 10; ++p) {
     // Check "A" Jacobian.
-    EXPECT_EQ(-1.0, jacobian_vect[0][2*p * 10 + p]);
+    EXPECT_EQ(-1.0, jacobian_vect[0][2 * p * 10 + p]);
     // Check "B" Jacobian.
-    EXPECT_EQ(+1.0, jacobian_vect[0][(2*p+1) * 10 + p]);
-    jacobian_vect[0][2*p * 10 + p] = 0.0;
-    jacobian_vect[0][(2*p+1) * 10 + p] = 0.0;
+    EXPECT_EQ(+1.0, jacobian_vect[0][(2 * p + 1) * 10 + p]);
+    jacobian_vect[0][2 * p * 10 + p] = 0.0;
+    jacobian_vect[0][(2 * p + 1) * 10 + p] = 0.0;
   }
 
   // Check "C" Jacobian for first parameter block.
@@ -309,7 +307,7 @@
 
 class ThreeParameterCostFunctorTest : public ::testing::Test {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     // Prepare the parameters.
     x_.resize(1);
     x_[0] = 0.0;
@@ -330,10 +328,10 @@
 
     // Prepare the cost function.
     typedef DynamicAutoDiffCostFunction<MyThreeParameterCostFunctor, 3>
-      DynamicMyThreeParameterCostFunction;
-    DynamicMyThreeParameterCostFunction * cost_function =
-      new DynamicMyThreeParameterCostFunction(
-        new MyThreeParameterCostFunctor());
+        DynamicMyThreeParameterCostFunction;
+    DynamicMyThreeParameterCostFunction* cost_function =
+        new DynamicMyThreeParameterCostFunction(
+            new MyThreeParameterCostFunctor());
     cost_function->AddParameterBlock(1);
     cost_function->AddParameterBlock(2);
     cost_function->AddParameterBlock(3);
@@ -431,9 +429,8 @@
 
 TEST_F(ThreeParameterCostFunctorTest, TestThreeParameterResiduals) {
   vector<double> residuals(7, -100000);
-  EXPECT_TRUE(cost_function_->Evaluate(parameter_blocks_.data(),
-                                       residuals.data(),
-                                       NULL));
+  EXPECT_TRUE(cost_function_->Evaluate(
+      parameter_blocks_.data(), residuals.data(), NULL));
   for (int i = 0; i < 7; ++i) {
     EXPECT_EQ(expected_residuals_[i], residuals[i]);
   }
@@ -447,9 +444,8 @@
   jacobian.push_back(jacobian_vect_[1].data());
   jacobian.push_back(jacobian_vect_[2].data());
 
-  EXPECT_TRUE(cost_function_->Evaluate(parameter_blocks_.data(),
-                                       residuals.data(),
-                                       jacobian.data()));
+  EXPECT_TRUE(cost_function_->Evaluate(
+      parameter_blocks_.data(), residuals.data(), jacobian.data()));
 
   for (int i = 0; i < 7; ++i) {
     EXPECT_EQ(expected_residuals_[i], residuals[i]);
@@ -477,9 +473,8 @@
   jacobian.push_back(jacobian_vect_[1].data());
   jacobian.push_back(NULL);
 
-  EXPECT_TRUE(cost_function_->Evaluate(parameter_blocks_.data(),
-                                       residuals.data(),
-                                       jacobian.data()));
+  EXPECT_TRUE(cost_function_->Evaluate(
+      parameter_blocks_.data(), residuals.data(), jacobian.data()));
 
   for (int i = 0; i < 7; ++i) {
     EXPECT_EQ(expected_residuals_[i], residuals[i]);
@@ -499,9 +494,8 @@
   jacobian.push_back(NULL);
   jacobian.push_back(jacobian_vect_[2].data());
 
-  EXPECT_TRUE(cost_function_->Evaluate(parameter_blocks_.data(),
-                                       residuals.data(),
-                                       jacobian.data()));
+  EXPECT_TRUE(cost_function_->Evaluate(
+      parameter_blocks_.data(), residuals.data(), jacobian.data()));
 
   for (int i = 0; i < 7; ++i) {
     EXPECT_EQ(expected_residuals_[i], residuals[i]);
@@ -548,7 +542,7 @@
 
 class SixParameterCostFunctorTest : public ::testing::Test {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     // Prepare the parameters.
     x0_ = 0.0;
     y0_ = 1.0;
@@ -567,10 +561,9 @@
 
     // Prepare the cost function.
     typedef DynamicAutoDiffCostFunction<MySixParameterCostFunctor, 3>
-      DynamicMySixParameterCostFunction;
-    DynamicMySixParameterCostFunction * cost_function =
-      new DynamicMySixParameterCostFunction(
-        new MySixParameterCostFunctor());
+        DynamicMySixParameterCostFunction;
+    DynamicMySixParameterCostFunction* cost_function =
+        new DynamicMySixParameterCostFunction(new MySixParameterCostFunctor());
     for (int i = 0; i < 6; ++i) {
       cost_function->AddParameterBlock(1);
     }
@@ -675,9 +668,8 @@
 
 TEST_F(SixParameterCostFunctorTest, TestSixParameterResiduals) {
   vector<double> residuals(7, -100000);
-  EXPECT_TRUE(cost_function_->Evaluate(parameter_blocks_.data(),
-                                       residuals.data(),
-                                       NULL));
+  EXPECT_TRUE(cost_function_->Evaluate(
+      parameter_blocks_.data(), residuals.data(), NULL));
   for (int i = 0; i < 7; ++i) {
     EXPECT_EQ(expected_residuals_[i], residuals[i]);
   }
@@ -694,9 +686,8 @@
   jacobian.push_back(jacobian_vect_[4].data());
   jacobian.push_back(jacobian_vect_[5].data());
 
-  EXPECT_TRUE(cost_function_->Evaluate(parameter_blocks_.data(),
-                                       residuals.data(),
-                                       jacobian.data()));
+  EXPECT_TRUE(cost_function_->Evaluate(
+      parameter_blocks_.data(), residuals.data(), jacobian.data()));
 
   for (int i = 0; i < 7; ++i) {
     EXPECT_EQ(expected_residuals_[i], residuals[i]);
@@ -720,9 +711,8 @@
   jacobian.push_back(jacobian_vect_[4].data());
   jacobian.push_back(NULL);
 
-  EXPECT_TRUE(cost_function_->Evaluate(parameter_blocks_.data(),
-                                       residuals.data(),
-                                       jacobian.data()));
+  EXPECT_TRUE(cost_function_->Evaluate(
+      parameter_blocks_.data(), residuals.data(), jacobian.data()));
 
   for (int i = 0; i < 7; ++i) {
     EXPECT_EQ(expected_residuals_[i], residuals[i]);
@@ -751,9 +741,8 @@
   jacobian.push_back(NULL);
   jacobian.push_back(jacobian_vect_[5].data());
 
-  EXPECT_TRUE(cost_function_->Evaluate(parameter_blocks_.data(),
-                                       residuals.data(),
-                                       jacobian.data()));
+  EXPECT_TRUE(cost_function_->Evaluate(
+      parameter_blocks_.data(), residuals.data(), jacobian.data()));
 
   for (int i = 0; i < 7; ++i) {
     EXPECT_EQ(expected_residuals_[i], residuals[i]);
@@ -771,5 +760,51 @@
   }
 }
 
+class ValueError {
+ public:
+  explicit ValueError(double target_value) : target_value_(target_value) {}
+
+  template <typename T>
+  bool operator()(const T* value, T* residual) const {
+    *residual = *value - T(target_value_);
+    return true;
+  }
+
+ protected:
+  double target_value_;
+};
+
+class DynamicValueError {
+ public:
+  explicit DynamicValueError(double target_value)
+      : target_value_(target_value) {}
+
+  template <typename T>
+  bool operator()(T const* const* parameters, T* residual) const {
+    residual[0] = T(target_value_) - parameters[0][0];
+    return true;
+  }
+
+ protected:
+  double target_value_;
+};
+
+TEST(DynamicAutoDiffCostFunction,
+     EvaluateWithEmptyJacobiansArrayComputesResidual) {
+  const double target_value = 1.0;
+  double parameter = 0;
+  ceres::DynamicAutoDiffCostFunction<DynamicValueError, 1> cost_function(
+      new DynamicValueError(target_value));
+  cost_function.AddParameterBlock(1);
+  cost_function.SetNumResiduals(1);
+
+  double* parameter_blocks[1] = {&parameter};
+  double* jacobians[1] = {nullptr};
+  double residual;
+
+  EXPECT_TRUE(cost_function.Evaluate(parameter_blocks, &residual, jacobians));
+  EXPECT_EQ(residual, target_value);
+}
+
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/dynamic_compressed_row_finalizer.h b/internal/ceres/dynamic_compressed_row_finalizer.h
index a25a308..30c98d8 100644
--- a/internal/ceres/dynamic_compressed_row_finalizer.h
+++ b/internal/ceres/dynamic_compressed_row_finalizer.h
@@ -40,7 +40,7 @@
 struct DynamicCompressedRowJacobianFinalizer {
   void operator()(SparseMatrix* base_jacobian, int num_parameters) {
     DynamicCompressedRowSparseMatrix* jacobian =
-      down_cast<DynamicCompressedRowSparseMatrix*>(base_jacobian);
+        down_cast<DynamicCompressedRowSparseMatrix*>(base_jacobian);
     jacobian->Finalize(num_parameters);
   }
 };
diff --git a/internal/ceres/dynamic_compressed_row_jacobian_writer.cc b/internal/ceres/dynamic_compressed_row_jacobian_writer.cc
index acc372a..1749449 100644
--- a/internal/ceres/dynamic_compressed_row_jacobian_writer.cc
+++ b/internal/ceres/dynamic_compressed_row_jacobian_writer.cc
@@ -29,6 +29,7 @@
 // Author: richie.stebbing@gmail.com (Richard Stebbing)
 
 #include "ceres/dynamic_compressed_row_jacobian_writer.h"
+
 #include "ceres/casts.h"
 #include "ceres/compressed_row_jacobian_writer.h"
 #include "ceres/dynamic_compressed_row_sparse_matrix.h"
@@ -82,12 +83,13 @@
     const int parameter_block_jacobian_index =
         evaluated_jacobian_blocks[i].second;
     const int parameter_block_size = parameter_block->LocalSize();
+    const double* parameter_jacobian =
+        jacobians[parameter_block_jacobian_index];
 
     // For each parameter block only insert its non-zero entries.
     for (int r = 0; r < num_residuals; ++r) {
-      for (int c = 0; c < parameter_block_size; ++c) {
-        const double& v = jacobians[parameter_block_jacobian_index]
-                                   [r * parameter_block_size + c];
+      for (int c = 0; c < parameter_block_size; ++c, ++parameter_jacobian) {
+        const double v = *parameter_jacobian;
         // Only insert non-zero entries.
         if (v != 0.0) {
           jacobian->InsertEntry(
diff --git a/internal/ceres/dynamic_compressed_row_jacobian_writer.h b/internal/ceres/dynamic_compressed_row_jacobian_writer.h
index 6e5ac38..ef8fa25 100644
--- a/internal/ceres/dynamic_compressed_row_jacobian_writer.h
+++ b/internal/ceres/dynamic_compressed_row_jacobian_writer.h
@@ -47,8 +47,7 @@
  public:
   DynamicCompressedRowJacobianWriter(Evaluator::Options /* ignored */,
                                      Program* program)
-    : program_(program) {
-  }
+      : program_(program) {}
 
   // JacobianWriter interface.
 
@@ -70,7 +69,7 @@
   // This method is thread-safe over residual blocks (each `residual_id`).
   void Write(int residual_id,
              int residual_offset,
-             double **jacobians,
+             double** jacobians,
              SparseMatrix* base_jacobian);
 
  private:
diff --git a/internal/ceres/dynamic_compressed_row_sparse_matrix.cc b/internal/ceres/dynamic_compressed_row_sparse_matrix.cc
index f020768..936e682 100644
--- a/internal/ceres/dynamic_compressed_row_sparse_matrix.cc
+++ b/internal/ceres/dynamic_compressed_row_sparse_matrix.cc
@@ -28,22 +28,19 @@
 //
 // Author: richie.stebbing@gmail.com (Richard Stebbing)
 
-#include <cstring>
 #include "ceres/dynamic_compressed_row_sparse_matrix.h"
 
+#include <cstring>
+
 namespace ceres {
 namespace internal {
 
 DynamicCompressedRowSparseMatrix::DynamicCompressedRowSparseMatrix(
-  int num_rows,
-  int num_cols,
-  int initial_max_num_nonzeros)
-    : CompressedRowSparseMatrix(num_rows,
-                                num_cols,
-                                initial_max_num_nonzeros) {
-    dynamic_cols_.resize(num_rows);
-    dynamic_values_.resize(num_rows);
-  }
+    int num_rows, int num_cols, int initial_max_num_nonzeros)
+    : CompressedRowSparseMatrix(num_rows, num_cols, initial_max_num_nonzeros) {
+  dynamic_cols_.resize(num_rows);
+  dynamic_values_.resize(num_rows);
+}
 
 void DynamicCompressedRowSparseMatrix::InsertEntry(int row,
                                                    int col,
@@ -56,8 +53,7 @@
   dynamic_values_[row].push_back(value);
 }
 
-void DynamicCompressedRowSparseMatrix::ClearRows(int row_start,
-                                                 int num_rows) {
+void DynamicCompressedRowSparseMatrix::ClearRows(int row_start, int num_rows) {
   for (int r = 0; r < num_rows; ++r) {
     const int i = row_start + r;
     CHECK_GE(i, 0);
@@ -99,8 +95,8 @@
   mutable_rows()[num_rows()] = index_into_values_and_cols;
 
   CHECK_EQ(index_into_values_and_cols, num_jacobian_nonzeros)
-    << "Ceres bug: final index into values_ and cols_ should be equal to "
-    << "the number of jacobian nonzeros. Please contact the developers!";
+      << "Ceres bug: final index into values_ and cols_ should be equal to "
+      << "the number of jacobian nonzeros. Please contact the developers!";
 }
 
 }  // namespace internal
diff --git a/internal/ceres/dynamic_compressed_row_sparse_matrix.h b/internal/ceres/dynamic_compressed_row_sparse_matrix.h
index ad41da7..d06c36e 100644
--- a/internal/ceres/dynamic_compressed_row_sparse_matrix.h
+++ b/internal/ceres/dynamic_compressed_row_sparse_matrix.h
@@ -44,11 +44,13 @@
 #include <vector>
 
 #include "ceres/compressed_row_sparse_matrix.h"
+#include "ceres/internal/port.h"
 
 namespace ceres {
 namespace internal {
 
-class DynamicCompressedRowSparseMatrix : public CompressedRowSparseMatrix {
+class CERES_EXPORT_INTERNAL DynamicCompressedRowSparseMatrix
+    : public CompressedRowSparseMatrix {
  public:
   // Set the number of rows and columns for the underlyig
   // `CompressedRowSparseMatrix` and set the initial number of maximum non-zero
diff --git a/internal/ceres/dynamic_compressed_row_sparse_matrix_test.cc b/internal/ceres/dynamic_compressed_row_sparse_matrix_test.cc
index 3592557..95dc807 100644
--- a/internal/ceres/dynamic_compressed_row_sparse_matrix_test.cc
+++ b/internal/ceres/dynamic_compressed_row_sparse_matrix_test.cc
@@ -31,6 +31,7 @@
 #include "ceres/dynamic_compressed_row_sparse_matrix.h"
 
 #include <memory>
+
 #include "ceres/casts.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/internal/eigen.h"
@@ -46,7 +47,7 @@
 
 class DynamicCompressedRowSparseMatrixTest : public ::testing::Test {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     num_rows = 7;
     num_cols = 4;
 
@@ -60,14 +61,10 @@
     InitialiseDenseReference();
     InitialiseSparseMatrixReferences();
 
-    dcrsm.reset(new DynamicCompressedRowSparseMatrix(num_rows,
-                                                     num_cols,
-                                                     0));
+    dcrsm.reset(new DynamicCompressedRowSparseMatrix(num_rows, num_cols, 0));
   }
 
-  void Finalize() {
-    dcrsm->Finalize(num_additional_elements);
-  }
+  void Finalize() { dcrsm->Finalize(num_additional_elements); }
 
   void InitialiseDenseReference() {
     dense.resize(num_rows, num_cols);
@@ -96,9 +93,8 @@
     }
     ASSERT_EQ(values.size(), expected_num_nonzeros);
 
-    tsm.reset(new TripletSparseMatrix(num_rows,
-                                      num_cols,
-                                      expected_num_nonzeros));
+    tsm.reset(
+        new TripletSparseMatrix(num_rows, num_cols, expected_num_nonzeros));
     copy(rows.begin(), rows.end(), tsm->mutable_rows());
     copy(cols.begin(), cols.end(), tsm->mutable_cols());
     copy(values.begin(), values.end(), tsm->mutable_values());
diff --git a/internal/ceres/dynamic_numeric_diff_cost_function_test.cc b/internal/ceres/dynamic_numeric_diff_cost_function_test.cc
index b627eb7..0150f5e 100644
--- a/internal/ceres/dynamic_numeric_diff_cost_function_test.cc
+++ b/internal/ceres/dynamic_numeric_diff_cost_function_test.cc
@@ -29,10 +29,11 @@
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 //         mierle@gmail.com (Keir Mierle)
 
-#include <cstddef>
-
-#include <memory>
 #include "ceres/dynamic_numeric_diff_cost_function.h"
+
+#include <cstddef>
+#include <memory>
+
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -87,9 +88,8 @@
   vector<double*> parameter_blocks(2);
   parameter_blocks[0] = &param_block_0[0];
   parameter_blocks[1] = &param_block_1[0];
-  EXPECT_TRUE(cost_function.Evaluate(&parameter_blocks[0],
-                                     residuals.data(),
-                                     NULL));
+  EXPECT_TRUE(
+      cost_function.Evaluate(&parameter_blocks[0], residuals.data(), NULL));
   for (int r = 0; r < 10; ++r) {
     EXPECT_EQ(1.0 * r, residuals.at(r * 2));
     EXPECT_EQ(-1.0 * r, residuals.at(r * 2 + 1));
@@ -97,7 +97,6 @@
   EXPECT_EQ(0, residuals.at(20));
 }
 
-
 TEST(DynamicNumericdiffCostFunctionTest, TestJacobian) {
   // Test the residual counting.
   vector<double> param_block_0(10, 0.0);
@@ -128,9 +127,8 @@
   jacobian.push_back(jacobian_vect[1].data());
 
   // Test jacobian computation.
-  EXPECT_TRUE(cost_function.Evaluate(parameter_blocks.data(),
-                                     residuals.data(),
-                                     jacobian.data()));
+  EXPECT_TRUE(cost_function.Evaluate(
+      parameter_blocks.data(), residuals.data(), jacobian.data()));
 
   for (int r = 0; r < 10; ++r) {
     EXPECT_EQ(-1.0 * r, residuals.at(r * 2));
@@ -139,11 +137,11 @@
   EXPECT_EQ(420, residuals.at(20));
   for (int p = 0; p < 10; ++p) {
     // Check "A" Jacobian.
-    EXPECT_NEAR(-1.0, jacobian_vect[0][2*p * 10 + p], kTolerance);
+    EXPECT_NEAR(-1.0, jacobian_vect[0][2 * p * 10 + p], kTolerance);
     // Check "B" Jacobian.
-    EXPECT_NEAR(+1.0, jacobian_vect[0][(2*p+1) * 10 + p], kTolerance);
-    jacobian_vect[0][2*p * 10 + p] = 0.0;
-    jacobian_vect[0][(2*p+1) * 10 + p] = 0.0;
+    EXPECT_NEAR(+1.0, jacobian_vect[0][(2 * p + 1) * 10 + p], kTolerance);
+    jacobian_vect[0][2 * p * 10 + p] = 0.0;
+    jacobian_vect[0][(2 * p + 1) * 10 + p] = 0.0;
   }
 
   // Check "C" Jacobian for first parameter block.
@@ -165,7 +163,8 @@
   }
 }
 
-TEST(DynamicNumericdiffCostFunctionTest, JacobianWithFirstParameterBlockConstant) {  // NOLINT
+TEST(DynamicNumericdiffCostFunctionTest,
+     JacobianWithFirstParameterBlockConstant) {  // NOLINT
   // Test the residual counting.
   vector<double> param_block_0(10, 0.0);
   for (int i = 0; i < 10; ++i) {
@@ -195,9 +194,8 @@
   jacobian.push_back(jacobian_vect[1].data());
 
   // Test jacobian computation.
-  EXPECT_TRUE(cost_function.Evaluate(parameter_blocks.data(),
-                                     residuals.data(),
-                                     jacobian.data()));
+  EXPECT_TRUE(cost_function.Evaluate(
+      parameter_blocks.data(), residuals.data(), jacobian.data()));
 
   for (int r = 0; r < 10; ++r) {
     EXPECT_EQ(-1.0 * r, residuals.at(r * 2));
@@ -215,7 +213,8 @@
   }
 }
 
-TEST(DynamicNumericdiffCostFunctionTest, JacobianWithSecondParameterBlockConstant) {  // NOLINT
+TEST(DynamicNumericdiffCostFunctionTest,
+     JacobianWithSecondParameterBlockConstant) {  // NOLINT
   // Test the residual counting.
   vector<double> param_block_0(10, 0.0);
   for (int i = 0; i < 10; ++i) {
@@ -245,9 +244,8 @@
   jacobian.push_back(NULL);
 
   // Test jacobian computation.
-  EXPECT_TRUE(cost_function.Evaluate(parameter_blocks.data(),
-                                     residuals.data(),
-                                     jacobian.data()));
+  EXPECT_TRUE(cost_function.Evaluate(
+      parameter_blocks.data(), residuals.data(), jacobian.data()));
 
   for (int r = 0; r < 10; ++r) {
     EXPECT_EQ(-1.0 * r, residuals.at(r * 2));
@@ -256,11 +254,11 @@
   EXPECT_EQ(420, residuals.at(20));
   for (int p = 0; p < 10; ++p) {
     // Check "A" Jacobian.
-    EXPECT_NEAR(-1.0, jacobian_vect[0][2*p * 10 + p], kTolerance);
+    EXPECT_NEAR(-1.0, jacobian_vect[0][2 * p * 10 + p], kTolerance);
     // Check "B" Jacobian.
-    EXPECT_NEAR(+1.0, jacobian_vect[0][(2*p+1) * 10 + p], kTolerance);
-    jacobian_vect[0][2*p * 10 + p] = 0.0;
-    jacobian_vect[0][(2*p+1) * 10 + p] = 0.0;
+    EXPECT_NEAR(+1.0, jacobian_vect[0][(2 * p + 1) * 10 + p], kTolerance);
+    jacobian_vect[0][2 * p * 10 + p] = 0.0;
+    jacobian_vect[0][(2 * p + 1) * 10 + p] = 0.0;
   }
 
   // Check "C" Jacobian for first parameter block.
@@ -310,7 +308,7 @@
 
 class ThreeParameterCostFunctorTest : public ::testing::Test {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     // Prepare the parameters.
     x_.resize(1);
     x_[0] = 0.0;
@@ -331,10 +329,10 @@
 
     // Prepare the cost function.
     typedef DynamicNumericDiffCostFunction<MyThreeParameterCostFunctor>
-      DynamicMyThreeParameterCostFunction;
-    DynamicMyThreeParameterCostFunction * cost_function =
-      new DynamicMyThreeParameterCostFunction(
-        new MyThreeParameterCostFunctor());
+        DynamicMyThreeParameterCostFunction;
+    DynamicMyThreeParameterCostFunction* cost_function =
+        new DynamicMyThreeParameterCostFunction(
+            new MyThreeParameterCostFunctor());
     cost_function->AddParameterBlock(1);
     cost_function->AddParameterBlock(2);
     cost_function->AddParameterBlock(3);
@@ -432,9 +430,8 @@
 
 TEST_F(ThreeParameterCostFunctorTest, TestThreeParameterResiduals) {
   vector<double> residuals(7, -100000);
-  EXPECT_TRUE(cost_function_->Evaluate(parameter_blocks_.data(),
-                                       residuals.data(),
-                                       NULL));
+  EXPECT_TRUE(cost_function_->Evaluate(
+      parameter_blocks_.data(), residuals.data(), NULL));
   for (int i = 0; i < 7; ++i) {
     EXPECT_EQ(expected_residuals_[i], residuals[i]);
   }
@@ -448,9 +445,8 @@
   jacobian.push_back(jacobian_vect_[1].data());
   jacobian.push_back(jacobian_vect_[2].data());
 
-  EXPECT_TRUE(cost_function_->Evaluate(parameter_blocks_.data(),
-                                       residuals.data(),
-                                       jacobian.data()));
+  EXPECT_TRUE(cost_function_->Evaluate(
+      parameter_blocks_.data(), residuals.data(), jacobian.data()));
 
   for (int i = 0; i < 7; ++i) {
     EXPECT_EQ(expected_residuals_[i], residuals[i]);
@@ -478,9 +474,8 @@
   jacobian.push_back(jacobian_vect_[1].data());
   jacobian.push_back(NULL);
 
-  EXPECT_TRUE(cost_function_->Evaluate(parameter_blocks_.data(),
-                                       residuals.data(),
-                                       jacobian.data()));
+  EXPECT_TRUE(cost_function_->Evaluate(
+      parameter_blocks_.data(), residuals.data(), jacobian.data()));
 
   for (int i = 0; i < 7; ++i) {
     EXPECT_EQ(expected_residuals_[i], residuals[i]);
@@ -500,9 +495,8 @@
   jacobian.push_back(NULL);
   jacobian.push_back(jacobian_vect_[2].data());
 
-  EXPECT_TRUE(cost_function_->Evaluate(parameter_blocks_.data(),
-                                       residuals.data(),
-                                       jacobian.data()));
+  EXPECT_TRUE(cost_function_->Evaluate(
+      parameter_blocks_.data(), residuals.data(), jacobian.data()));
 
   for (int i = 0; i < 7; ++i) {
     EXPECT_EQ(expected_residuals_[i], residuals[i]);
diff --git a/internal/ceres/dynamic_sparse_normal_cholesky_solver.cc b/internal/ceres/dynamic_sparse_normal_cholesky_solver.cc
index f966083..d31c422 100644
--- a/internal/ceres/dynamic_sparse_normal_cholesky_solver.cc
+++ b/internal/ceres/dynamic_sparse_normal_cholesky_solver.cc
@@ -92,8 +92,10 @@
       summary = SolveImplUsingEigen(A, x);
       break;
     default:
-      LOG(FATAL) << "Unknown sparse linear algebra library : "
-                 << options_.sparse_linear_algebra_library_type;
+      LOG(FATAL) << "Unsupported sparse linear algebra library for "
+                 << "dynamic sparsity: "
+                 << SparseLinearAlgebraLibraryTypeToString(
+                        options_.sparse_linear_algebra_library_type);
   }
 
   if (per_solve_options.D != nullptr) {
diff --git a/internal/ceres/dynamic_sparse_normal_cholesky_solver.h b/internal/ceres/dynamic_sparse_normal_cholesky_solver.h
index 17be90c..36118ba 100644
--- a/internal/ceres/dynamic_sparse_normal_cholesky_solver.h
+++ b/internal/ceres/dynamic_sparse_normal_cholesky_solver.h
@@ -35,7 +35,9 @@
 #define CERES_INTERNAL_DYNAMIC_SPARSE_NORMAL_CHOLESKY_SOLVER_H_
 
 // This include must come before any #ifndef check on Ceres compile options.
+// clang-format off
 #include "ceres/internal/port.h"
+// clang-format on
 
 #include "ceres/linear_solver.h"
 
@@ -59,23 +61,19 @@
   virtual ~DynamicSparseNormalCholeskySolver() {}
 
  private:
-  virtual LinearSolver::Summary SolveImpl(
-      CompressedRowSparseMatrix* A,
-      const double* b,
-      const LinearSolver::PerSolveOptions& options,
-      double* x);
+  LinearSolver::Summary SolveImpl(CompressedRowSparseMatrix* A,
+                                  const double* b,
+                                  const LinearSolver::PerSolveOptions& options,
+                                  double* x) final;
 
-  LinearSolver::Summary SolveImplUsingSuiteSparse(
-      CompressedRowSparseMatrix* A,
-      double* rhs_and_solution);
+  LinearSolver::Summary SolveImplUsingSuiteSparse(CompressedRowSparseMatrix* A,
+                                                  double* rhs_and_solution);
 
-  LinearSolver::Summary SolveImplUsingCXSparse(
-      CompressedRowSparseMatrix* A,
-      double* rhs_and_solution);
+  LinearSolver::Summary SolveImplUsingCXSparse(CompressedRowSparseMatrix* A,
+                                               double* rhs_and_solution);
 
-  LinearSolver::Summary SolveImplUsingEigen(
-      CompressedRowSparseMatrix* A,
-      double* rhs_and_solution);
+  LinearSolver::Summary SolveImplUsingEigen(CompressedRowSparseMatrix* A,
+                                            double* rhs_and_solution);
 
   const LinearSolver::Options options_;
 };
diff --git a/internal/ceres/dynamic_sparse_normal_cholesky_solver_test.cc b/internal/ceres/dynamic_sparse_normal_cholesky_solver_test.cc
index 4fe06f8..8bf609e 100644
--- a/internal/ceres/dynamic_sparse_normal_cholesky_solver_test.cc
+++ b/internal/ceres/dynamic_sparse_normal_cholesky_solver_test.cc
@@ -29,6 +29,8 @@
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
 #include <memory>
+
+#include "Eigen/Cholesky"
 #include "ceres/casts.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/context_impl.h"
@@ -39,8 +41,6 @@
 #include "glog/logging.h"
 #include "gtest/gtest.h"
 
-#include "Eigen/Cholesky"
-
 namespace ceres {
 namespace internal {
 
@@ -49,7 +49,7 @@
 // sparsity.
 class DynamicSparseNormalCholeskySolverTest : public ::testing::Test {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     std::unique_ptr<LinearLeastSquaresProblem> problem(
         CreateLinearLeastSquaresProblemFromId(1));
     A_.reset(CompressedRowSparseMatrix::FromTripletSparseMatrix(
diff --git a/internal/ceres/dynamic_sparsity_test.cc b/internal/ceres/dynamic_sparsity_test.cc
index 5fe60f4..12e62ef 100644
--- a/internal/ceres/dynamic_sparsity_test.cc
+++ b/internal/ceres/dynamic_sparsity_test.cc
@@ -33,6 +33,7 @@
 
 #include <cmath>
 #include <vector>
+
 #include "ceres/ceres.h"
 #include "glog/logging.h"
 #include "gtest/gtest.h"
@@ -53,6 +54,7 @@
 
 const int kYRows = 212;
 const int kYCols = 2;
+// clang-format off
 const double kYData[kYRows * kYCols] = {
   +3.871364e+00, +9.916027e-01,
   +3.864003e+00, +1.034148e+00,
@@ -267,11 +269,16 @@
   +3.870542e+00, +9.996121e-01,
   +3.865424e+00, +1.028474e+00
 };
+// clang-format on
 
 ConstMatrixRef kY(kYData, kYRows, kYCols);
 
 class PointToLineSegmentContourCostFunction : public CostFunction {
  public:
+  // This class needs to have an Eigen aligned operator new as it contains
+  // fixed-size Eigen types.
+  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+
   PointToLineSegmentContourCostFunction(const int num_segments,
                                         const Eigen::Vector2d& y)
       : num_segments_(num_segments), y_(y) {
@@ -284,9 +291,9 @@
     set_num_residuals(2);
   }
 
-  virtual bool Evaluate(const double* const* x,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(const double* const* x,
+                double* residuals,
+                double** jacobians) const final {
     // Convert the preimage position `t` into a segment index `i0` and the
     // line segment interpolation parameter `u`. `i1` is the index of the next
     // control point.
@@ -323,7 +330,8 @@
     return true;
   }
 
-  static CostFunction* Create(const int num_segments, const Eigen::Vector2d& y) {
+  static CostFunction* Create(const int num_segments,
+                              const Eigen::Vector2d& y) {
     return new PointToLineSegmentContourCostFunction(num_segments, y);
   }
 
diff --git a/internal/ceres/eigensparse.cc b/internal/ceres/eigensparse.cc
index 9847bfd..22ed2c4 100644
--- a/internal/ceres/eigensparse.cc
+++ b/internal/ceres/eigensparse.cc
@@ -33,6 +33,7 @@
 #ifdef CERES_USE_EIGEN_SPARSE
 
 #include <sstream>
+
 #include "Eigen/SparseCholesky"
 #include "Eigen/SparseCore"
 #include "ceres/compressed_row_sparse_matrix.h"
@@ -48,11 +49,11 @@
  public:
   EigenSparseCholeskyTemplate() : analyzed_(false) {}
   virtual ~EigenSparseCholeskyTemplate() {}
-  virtual CompressedRowSparseMatrix::StorageType StorageType() const {
+  CompressedRowSparseMatrix::StorageType StorageType() const final {
     return CompressedRowSparseMatrix::LOWER_TRIANGULAR;
   }
 
-  virtual LinearSolverTerminationType Factorize(
+  LinearSolverTerminationType Factorize(
       const Eigen::SparseMatrix<typename Solver::Scalar>& lhs,
       std::string* message) {
     if (!analyzed_) {
@@ -104,8 +105,8 @@
     return LINEAR_SOLVER_SUCCESS;
   }
 
-  virtual LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
-                                                std::string* message) {
+  LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
+                                        std::string* message) final {
     CHECK_EQ(lhs->storage_type(), StorageType());
 
     typename Solver::Scalar* values_ptr = NULL;
@@ -142,10 +143,6 @@
     const OrderingType ordering_type) {
   std::unique_ptr<SparseCholesky> sparse_cholesky;
 
-  // The preprocessor gymnastics here are dealing with the fact that
-  // before version 3.2.2, Eigen did not support a third template
-  // parameter to specify the ordering and it always defaults to AMD.
-#if EIGEN_VERSION_AT_LEAST(3, 2, 2)
   typedef Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>,
                                 Eigen::Upper,
                                 Eigen::AMDOrdering<int>>
@@ -160,11 +157,6 @@
     sparse_cholesky.reset(
         new EigenSparseCholeskyTemplate<WithNaturalOrdering>());
   }
-#else
-  typedef Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>, Eigen::Upper>
-      WithAMDOrdering;
-  sparse_cholesky.reset(new EigenSparseCholeskyTemplate<WithAMDOrdering>());
-#endif
   return sparse_cholesky;
 }
 
@@ -173,10 +165,6 @@
 std::unique_ptr<SparseCholesky> FloatEigenSparseCholesky::Create(
     const OrderingType ordering_type) {
   std::unique_ptr<SparseCholesky> sparse_cholesky;
-  // The preprocessor gymnastics here are dealing with the fact that
-  // before version 3.2.2, Eigen did not support a third template
-  // parameter to specify the ordering and it always defaults to AMD.
-#if EIGEN_VERSION_AT_LEAST(3, 2, 2)
   typedef Eigen::SimplicialLDLT<Eigen::SparseMatrix<float>,
                                 Eigen::Upper,
                                 Eigen::AMDOrdering<int>>
@@ -191,11 +179,6 @@
     sparse_cholesky.reset(
         new EigenSparseCholeskyTemplate<WithNaturalOrdering>());
   }
-#else
-  typedef Eigen::SimplicialLDLT<Eigen::SparseMatrix<float>, Eigen::Upper>
-      WithAMDOrdering;
-  sparse_cholesky.reset(new EigenSparseCholeskyTemplate<WithAMDOrdering>());
-#endif
   return sparse_cholesky;
 }
 
diff --git a/internal/ceres/eigensparse.h b/internal/ceres/eigensparse.h
index 2e6c6f0..bb89c2c 100644
--- a/internal/ceres/eigensparse.h
+++ b/internal/ceres/eigensparse.h
@@ -56,8 +56,8 @@
 
   // SparseCholesky interface.
   virtual ~EigenSparseCholesky();
-  virtual LinearSolverTerminationType Factorize(
-      CompressedRowSparseMatrix* lhs, std::string* message) = 0;
+  virtual LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
+                                                std::string* message) = 0;
   virtual CompressedRowSparseMatrix::StorageType StorageType() const = 0;
   virtual LinearSolverTerminationType Solve(const double* rhs,
                                             double* solution,
@@ -74,8 +74,8 @@
 
   // SparseCholesky interface.
   virtual ~FloatEigenSparseCholesky();
-  virtual LinearSolverTerminationType Factorize(
-      CompressedRowSparseMatrix* lhs, std::string* message) = 0;
+  virtual LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
+                                                std::string* message) = 0;
   virtual CompressedRowSparseMatrix::StorageType StorageType() const = 0;
   virtual LinearSolverTerminationType Solve(const double* rhs,
                                             double* solution,
diff --git a/internal/ceres/evaluation_callback_test.cc b/internal/ceres/evaluation_callback_test.cc
index a28d5a8..0ca2625 100644
--- a/internal/ceres/evaluation_callback_test.cc
+++ b/internal/ceres/evaluation_callback_test.cc
@@ -28,23 +28,25 @@
 //
 // Author: mierle@gmail.com (Keir Mierle)
 
-#include "ceres/solver.h"
+#include "ceres/evaluation_callback.h"
 
 #include <cmath>
 #include <limits>
 #include <vector>
 
-#include "gtest/gtest.h"
-#include "ceres/sized_cost_function.h"
+#include "ceres/autodiff_cost_function.h"
 #include "ceres/problem.h"
 #include "ceres/problem_impl.h"
+#include "ceres/sized_cost_function.h"
+#include "ceres/solver.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
 
 // Use an inline hash function to avoid portability wrangling. Algorithm from
 // Daniel Bernstein, known as the "djb2" hash.
-template<typename T>
+template <typename T>
 uint64_t Djb2Hash(const T* data, const int size) {
   uint64_t hash = 5381;
   const uint8_t* data_as_bytes = reinterpret_cast<const uint8_t*>(data);
@@ -58,11 +60,9 @@
 
 // Generally multiple inheritance is a terrible idea, but in this (test)
 // case it makes for a relatively elegant test implementation.
-struct WigglyBowlCostFunctionAndEvaluationCallback :
-      SizedCostFunction<2, 2>,
-      EvaluationCallback  {
-
-  explicit WigglyBowlCostFunctionAndEvaluationCallback(double *parameter)
+struct WigglyBowlCostFunctionAndEvaluationCallback : SizedCostFunction<2, 2>,
+                                                     EvaluationCallback {
+  explicit WigglyBowlCostFunctionAndEvaluationCallback(double* parameter)
       : EvaluationCallback(),
         user_parameter_block(parameter),
         prepare_num_calls(0),
@@ -76,8 +76,8 @@
 
   // Evaluation callback interface. This checks that all the preconditions are
   // met at the point that Ceres calls into it.
-  virtual void PrepareForEvaluation(bool evaluate_jacobians,
-                                    bool new_evaluation_point) {
+  void PrepareForEvaluation(bool evaluate_jacobians,
+                            bool new_evaluation_point) final {
     // At this point, the incoming parameters are implicitly pushed by Ceres
     // into the user parameter blocks; in contrast to in Evaluate().
     uint64_t incoming_parameter_hash = Djb2Hash(user_parameter_block, 2);
@@ -110,9 +110,9 @@
 
   // Cost function interface. This checks that preconditions that were
   // set as part of the PrepareForEvaluation() call are met in this one.
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     // Cost function implementation of the "Wiggly Bowl" function:
     //
     //   1/2 * [(y - a*sin(x))^2 + x^2],
@@ -133,10 +133,10 @@
     residuals[0] = y - a * sin(x);
     residuals[1] = x;
     if (jacobians != NULL) {
-      (*jacobians)[2 * 0 + 0] = - a * cos(x);  // df1/dx
-      (*jacobians)[2 * 0 + 1] = 1.0;           // df1/dy
-      (*jacobians)[2 * 1 + 0] = 1.0;           // df2/dx
-      (*jacobians)[2 * 1 + 1] = 0.0;           // df2/dy
+      (*jacobians)[2 * 0 + 0] = -a * cos(x);  // df1/dx
+      (*jacobians)[2 * 0 + 1] = 1.0;          // df1/dy
+      (*jacobians)[2 * 1 + 0] = 1.0;          // df2/dx
+      (*jacobians)[2 * 1 + 1] = 0.0;          // df2/dy
     }
 
     uint64_t incoming_parameter_hash = Djb2Hash(*parameters, 2);
@@ -193,14 +193,14 @@
 
   WigglyBowlCostFunctionAndEvaluationCallback cost_function(parameters);
   Problem::Options problem_options;
+  problem_options.evaluation_callback = &cost_function;
   problem_options.cost_function_ownership = DO_NOT_TAKE_OWNERSHIP;
   Problem problem(problem_options);
   problem.AddResidualBlock(&cost_function, NULL, parameters);
 
   Solver::Options options;
   options.linear_solver_type = DENSE_QR;
-  options.max_num_iterations = 300;  // Cost function is hard.
-  options.evaluation_callback = &cost_function;
+  options.max_num_iterations = 50;
 
   // Run the solve. Checking is done inside the cost function / callback.
   Solver::Summary summary;
@@ -211,27 +211,106 @@
   EXPECT_GT(summary.num_unsuccessful_steps, 10);
 
   // Ensure PrepareForEvaluation() is called the appropriate number of times.
-  EXPECT_EQ(cost_function.prepare_num_calls,
-            // Unsuccessful steps are evaluated only once (no jacobians).
-            summary.num_unsuccessful_steps +
-            // Successful steps are evaluated twice: with and without jacobians.
-            2 * summary.num_successful_steps
-            // Final iteration doesn't re-evaluate the jacobian.
-            // Note: This may be sensitive to tweaks to the TR algorithm; if
-            // this becomes too brittle, remove this EXPECT_EQ() entirely.
-            - 1);
+  EXPECT_EQ(
+      cost_function.prepare_num_calls,
+      // Unsuccessful steps are evaluated only once (no jacobians).
+      summary.num_unsuccessful_steps +
+          // Successful steps are evaluated twice: with and without jacobians.
+          2 * summary.num_successful_steps
+          // Final iteration doesn't re-evaluate the jacobian.
+          // Note: This may be sensitive to tweaks to the TR algorithm; if
+          // this becomes too brittle, remove this EXPECT_EQ() entirely.
+          - 1);
 
   // Ensure the callback calls ran a reasonable number of times.
   EXPECT_GT(cost_function.prepare_num_calls, 0);
   EXPECT_GT(cost_function.evaluate_num_calls, 0);
-  EXPECT_EQ(cost_function.prepare_num_calls,
-            cost_function.evaluate_num_calls);
+  EXPECT_EQ(cost_function.prepare_num_calls, cost_function.evaluate_num_calls);
 
   // Ensure that the parameters did actually change.
   EXPECT_NE(Djb2Hash(parameters, 2), original_parameters_hash);
 }
 
-void WithLineSearchMinimizerImpl(
+// r = 1 - x
+struct LinearResidual {
+  template <typename T>
+  bool operator()(const T* x, T* residuals) const {
+    residuals[0] = 1.0 - x[0];
+    return true;
+  }
+
+  static CostFunction* Create() {
+    return new AutoDiffCostFunction<LinearResidual, 1, 1>(new LinearResidual);
+  };
+};
+
+// Increments a counter everytime PrepareForEvaluation is called.
+class IncrementingEvaluationCallback : public EvaluationCallback {
+ public:
+  void PrepareForEvaluation(bool evaluate_jacobians,
+                            bool new_evaluation_point) final {
+    (void)evaluate_jacobians;
+    (void)new_evaluation_point;
+    counter_ += 1.0;
+  }
+
+  const double counter() const { return counter_; }
+
+ private:
+  double counter_ = -1;
+};
+
+// r = IncrementingEvaluationCallback::counter - x
+struct EvaluationCallbackResidual {
+  explicit EvaluationCallbackResidual(
+      const IncrementingEvaluationCallback& callback)
+      : callback(callback) {}
+
+  template <typename T>
+  bool operator()(const T* x, T* residuals) const {
+    residuals[0] = callback.counter() - x[0];
+    return true;
+  }
+
+  const IncrementingEvaluationCallback& callback;
+
+  static CostFunction* Create(IncrementingEvaluationCallback& callback) {
+    return new AutoDiffCostFunction<EvaluationCallbackResidual, 1, 1>(
+        new EvaluationCallbackResidual(callback));
+  };
+};
+
+// The following test, constructs a problem with residual blocks all
+// of whose parameters are constant, so they are evaluated once
+// outside the Minimizer to compute Solver::Summary::fixed_cost.
+//
+// The cost function for this residual block depends on the
+// IncrementingEvaluationCallback::counter_, by checking the value of
+// the fixed cost, we can check if the IncrementingEvaluationCallback
+// was called.
+TEST(EvaluationCallback, EvaluationCallbackIsCalledBeforeFixedCostIsEvaluated) {
+  double x = 1;
+  double y = 2;
+  std::unique_ptr<IncrementingEvaluationCallback> callback(
+      new IncrementingEvaluationCallback);
+  Problem::Options problem_options;
+  problem_options.evaluation_callback = callback.get();
+  Problem problem(problem_options);
+  problem.AddResidualBlock(LinearResidual::Create(), nullptr, &x);
+  problem.AddResidualBlock(
+      EvaluationCallbackResidual::Create(*callback), nullptr, &y);
+  problem.SetParameterBlockConstant(&y);
+
+  Solver::Options options;
+  options.linear_solver_type = DENSE_QR;
+  Solver::Summary summary;
+  Solve(options, &problem, &summary);
+  EXPECT_EQ(summary.fixed_cost, 2.0);
+  EXPECT_EQ(summary.final_cost, summary.fixed_cost);
+  EXPECT_GT(callback->counter(), 0);
+}
+
+static void WithLineSearchMinimizerImpl(
     LineSearchType line_search,
     LineSearchDirectionType line_search_direction,
     LineSearchInterpolationType line_search_interpolation) {
@@ -240,15 +319,16 @@
 
   WigglyBowlCostFunctionAndEvaluationCallback cost_function(parameters);
   Problem::Options problem_options;
+  problem_options.evaluation_callback = &cost_function;
   problem_options.cost_function_ownership = DO_NOT_TAKE_OWNERSHIP;
   Problem problem(problem_options);
   problem.AddResidualBlock(&cost_function, NULL, parameters);
 
   Solver::Options options;
   options.linear_solver_type = DENSE_QR;
-  options.max_num_iterations = 300;  // Cost function is hard.
+  options.max_num_iterations = 50;
   options.minimizer_type = ceres::LINE_SEARCH;
-  options.evaluation_callback = &cost_function;
+
   options.line_search_type = line_search;
   options.line_search_direction_type = line_search_direction;
   options.line_search_interpolation_type = line_search_interpolation;
@@ -260,8 +340,7 @@
   // Ensure the callback calls ran a reasonable number of times.
   EXPECT_GT(summary.num_line_search_steps, 10);
   EXPECT_GT(cost_function.prepare_num_calls, 30);
-  EXPECT_EQ(cost_function.prepare_num_calls,
-            cost_function.evaluate_num_calls);
+  EXPECT_EQ(cost_function.prepare_num_calls, cost_function.evaluate_num_calls);
 
   // Ensure that the parameters did actually change.
   EXPECT_NE(Djb2Hash(parameters, 2), original_parameters_hash);
diff --git a/internal/ceres/evaluator.cc b/internal/ceres/evaluator.cc
index 8387983..5168741 100644
--- a/internal/ceres/evaluator.cc
+++ b/internal/ceres/evaluator.cc
@@ -28,7 +28,10 @@
 //
 // Author: keir@google.com (Keir Mierle)
 
+#include "ceres/evaluator.h"
+
 #include <vector>
+
 #include "ceres/block_evaluate_preparer.h"
 #include "ceres/block_jacobian_writer.h"
 #include "ceres/compressed_row_jacobian_writer.h"
@@ -37,7 +40,6 @@
 #include "ceres/dense_jacobian_writer.h"
 #include "ceres/dynamic_compressed_row_finalizer.h"
 #include "ceres/dynamic_compressed_row_jacobian_writer.h"
-#include "ceres/evaluator.h"
 #include "ceres/internal/port.h"
 #include "ceres/program_evaluator.h"
 #include "ceres/scratch_evaluate_preparer.h"
@@ -56,26 +58,23 @@
   switch (options.linear_solver_type) {
     case DENSE_QR:
     case DENSE_NORMAL_CHOLESKY:
-      return new ProgramEvaluator<ScratchEvaluatePreparer,
-                                  DenseJacobianWriter>(options,
-                                                       program);
+      return new ProgramEvaluator<ScratchEvaluatePreparer, DenseJacobianWriter>(
+          options, program);
     case DENSE_SCHUR:
     case SPARSE_SCHUR:
     case ITERATIVE_SCHUR:
     case CGNR:
-      return new ProgramEvaluator<BlockEvaluatePreparer,
-                                  BlockJacobianWriter>(options,
-                                                       program);
+      return new ProgramEvaluator<BlockEvaluatePreparer, BlockJacobianWriter>(
+          options, program);
     case SPARSE_NORMAL_CHOLESKY:
       if (options.dynamic_sparsity) {
         return new ProgramEvaluator<ScratchEvaluatePreparer,
                                     DynamicCompressedRowJacobianWriter,
                                     DynamicCompressedRowJacobianFinalizer>(
-                                        options, program);
+            options, program);
       } else {
-        return new ProgramEvaluator<BlockEvaluatePreparer,
-                                    BlockJacobianWriter>(options,
-                                                         program);
+        return new ProgramEvaluator<BlockEvaluatePreparer, BlockJacobianWriter>(
+            options, program);
       }
 
     default:
diff --git a/internal/ceres/evaluator.h b/internal/ceres/evaluator.h
index b820958..9cf4259 100644
--- a/internal/ceres/evaluator.h
+++ b/internal/ceres/evaluator.h
@@ -55,7 +55,7 @@
 // function that is useful for an optimizer that wants to minimize the least
 // squares objective. This insulates the optimizer from issues like Jacobian
 // storage, parameterization, etc.
-class Evaluator {
+class CERES_EXPORT_INTERNAL Evaluator {
  public:
   virtual ~Evaluator();
 
@@ -124,12 +124,8 @@
                 double* residuals,
                 double* gradient,
                 SparseMatrix* jacobian) {
-    return Evaluate(EvaluateOptions(),
-                    state,
-                    cost,
-                    residuals,
-                    gradient,
-                    jacobian);
+    return Evaluate(
+        EvaluateOptions(), state, cost, residuals, gradient, jacobian);
   }
 
   // Make a change delta (of size NumEffectiveParameters()) to state (of size
@@ -152,7 +148,7 @@
 
   // This is the effective number of parameters that the optimizer may adjust.
   // This applies when there are parameterizations on some of the parameters.
-  virtual int NumEffectiveParameters()  const = 0;
+  virtual int NumEffectiveParameters() const = 0;
 
   // The number of residuals in the optimization problem.
   virtual int NumResiduals() const = 0;
diff --git a/internal/ceres/evaluator_test.cc b/internal/ceres/evaluator_test.cc
index a156b89..5ddb733 100644
--- a/internal/ceres/evaluator_test.cc
+++ b/internal/ceres/evaluator_test.cc
@@ -34,6 +34,7 @@
 #include "ceres/evaluator.h"
 
 #include <memory>
+
 #include "ceres/casts.h"
 #include "ceres/cost_function.h"
 #include "ceres/crs_matrix.h"
@@ -64,9 +65,9 @@
   explicit ParameterIgnoringCostFunction(bool succeeds = true)
       : succeeds_(succeeds) {}
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     for (int i = 0; i < Base::num_residuals(); ++i) {
       residuals[i] = i + 1;
     }
@@ -105,17 +106,16 @@
   EvaluatorTestOptions(LinearSolverType linear_solver_type,
                        int num_eliminate_blocks,
                        bool dynamic_sparsity = false)
-    : linear_solver_type(linear_solver_type),
-      num_eliminate_blocks(num_eliminate_blocks),
-      dynamic_sparsity(dynamic_sparsity) {}
+      : linear_solver_type(linear_solver_type),
+        num_eliminate_blocks(num_eliminate_blocks),
+        dynamic_sparsity(dynamic_sparsity) {}
 
   LinearSolverType linear_solver_type;
   int num_eliminate_blocks;
   bool dynamic_sparsity;
 };
 
-struct EvaluatorTest
-    : public ::testing::TestWithParam<EvaluatorTestOptions> {
+struct EvaluatorTest : public ::testing::TestWithParam<EvaluatorTestOptions> {
   Evaluator* CreateEvaluator(Program* program) {
     // This program is straight from the ProblemImpl, and so has no index/offset
     // yet; compute it here as required by the evaluator implementations.
@@ -123,13 +123,15 @@
 
     if (VLOG_IS_ON(1)) {
       string report;
-      StringAppendF(&report, "Creating evaluator with type: %d",
+      StringAppendF(&report,
+                    "Creating evaluator with type: %d",
                     GetParam().linear_solver_type);
       if (GetParam().linear_solver_type == SPARSE_NORMAL_CHOLESKY) {
-        StringAppendF(&report, ", dynamic_sparsity: %d",
-                      GetParam().dynamic_sparsity);
+        StringAppendF(
+            &report, ", dynamic_sparsity: %d", GetParam().dynamic_sparsity);
       }
-      StringAppendF(&report, " and num_eliminate_blocks: %d",
+      StringAppendF(&report,
+                    " and num_eliminate_blocks: %d",
                     GetParam().num_eliminate_blocks);
       VLOG(1) << report;
     }
@@ -142,7 +144,7 @@
     return Evaluator::Create(options, program, &error);
   }
 
-  void EvaluateAndCompare(ProblemImpl *problem,
+  void EvaluateAndCompare(ProblemImpl* problem,
                           int expected_num_rows,
                           int expected_num_cols,
                           double expected_cost,
@@ -171,12 +173,14 @@
 
     vector<double> state(evaluator->NumParameters());
 
+    // clang-format off
     ASSERT_TRUE(evaluator->Evaluate(
           &state[0],
           &cost,
           expected_residuals != nullptr ? &residuals[0]  : nullptr,
           expected_gradient  != nullptr ? &gradient[0]   : nullptr,
           expected_jacobian  != nullptr ? jacobian.get() : nullptr));
+    // clang-format on
 
     Matrix actual_jacobian;
     if (expected_jacobian != nullptr) {
@@ -196,15 +200,15 @@
   }
 
   // Try all combinations of parameters for the evaluator.
-  void CheckAllEvaluationCombinations(const ExpectedEvaluation &expected) {
+  void CheckAllEvaluationCombinations(const ExpectedEvaluation& expected) {
     for (int i = 0; i < 8; ++i) {
       EvaluateAndCompare(&problem,
                          expected.num_rows,
                          expected.num_cols,
                          expected.cost,
                          (i & 1) ? expected.residuals : nullptr,
-                         (i & 2) ? expected.gradient  : nullptr,
-                         (i & 4) ? expected.jacobian  : nullptr);
+                         (i & 2) ? expected.gradient : nullptr,
+                         (i & 4) ? expected.jacobian : nullptr);
     }
   }
 
@@ -216,16 +220,16 @@
   ProblemImpl problem;
 };
 
-void SetSparseMatrixConstant(SparseMatrix* sparse_matrix, double value) {
-  VectorRef(sparse_matrix->mutable_values(),
-            sparse_matrix->num_nonzeros()).setConstant(value);
+static void SetSparseMatrixConstant(SparseMatrix* sparse_matrix, double value) {
+  VectorRef(sparse_matrix->mutable_values(), sparse_matrix->num_nonzeros())
+      .setConstant(value);
 }
 
 TEST_P(EvaluatorTest, SingleResidualProblem) {
-  problem.AddResidualBlock(new ParameterIgnoringCostFunction<1, 3, 2, 3, 4>,
-                           nullptr,
-                           x, y, z);
+  problem.AddResidualBlock(
+      new ParameterIgnoringCostFunction<1, 3, 2, 3, 4>, nullptr, x, y, z);
 
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     3, 9,
@@ -245,14 +249,15 @@
       1, 2,   1, 2, 3,   1, 2, 3, 4
     }
   };
+  // clang-format on
   CheckAllEvaluationCombinations(expected);
 }
 
 TEST_P(EvaluatorTest, SingleResidualProblemWithPermutedParameters) {
   // Add the parameters in explicit order to force the ordering in the program.
-  problem.AddParameterBlock(x,  2);
-  problem.AddParameterBlock(y,  3);
-  problem.AddParameterBlock(z,  4);
+  problem.AddParameterBlock(x, 2);
+  problem.AddParameterBlock(y, 3);
+  problem.AddParameterBlock(z, 4);
 
   // Then use a cost function which is similar to the others, but swap around
   // the ordering of the parameters to the cost function. This shouldn't affect
@@ -260,10 +265,10 @@
   // At one point the compressed row evaluator had a bug that went undetected
   // for a long time, since by chance most users added parameters to the problem
   // in the same order that they occurred as parameters to a cost function.
-  problem.AddResidualBlock(new ParameterIgnoringCostFunction<1, 3, 4, 3, 2>,
-                           nullptr,
-                           z, y, x);
+  problem.AddResidualBlock(
+      new ParameterIgnoringCostFunction<1, 3, 4, 3, 2>, nullptr, z, y, x);
 
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     3, 9,
@@ -283,6 +288,7 @@
       1, 2,   1, 2, 3,   1, 2, 3, 4
     }
   };
+  // clang-format on
   CheckAllEvaluationCombinations(expected);
 }
 
@@ -303,10 +309,10 @@
   problem.AddParameterBlock(z, 4);
   problem.AddParameterBlock(d, 3);
 
-  problem.AddResidualBlock(new ParameterIgnoringCostFunction<1, 3, 2, 3, 4>,
-                           nullptr,
-                           x, y, z);
+  problem.AddResidualBlock(
+      new ParameterIgnoringCostFunction<1, 3, 2, 3, 4>, nullptr, x, y, z);
 
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     3, 16,
@@ -330,30 +336,29 @@
       0, 0,    1, 2,    0,    1, 2, 3,    0,    1, 2, 3, 4,    0, 0, 0
     }
   };
+  // clang-format on
   CheckAllEvaluationCombinations(expected);
 }
 
 TEST_P(EvaluatorTest, MultipleResidualProblem) {
   // Add the parameters in explicit order to force the ordering in the program.
-  problem.AddParameterBlock(x,  2);
-  problem.AddParameterBlock(y,  3);
-  problem.AddParameterBlock(z,  4);
+  problem.AddParameterBlock(x, 2);
+  problem.AddParameterBlock(y, 3);
+  problem.AddParameterBlock(z, 4);
 
   // f(x, y) in R^2
-  problem.AddResidualBlock(new ParameterIgnoringCostFunction<1, 2, 2, 3>,
-                           nullptr,
-                           x, y);
+  problem.AddResidualBlock(
+      new ParameterIgnoringCostFunction<1, 2, 2, 3>, nullptr, x, y);
 
   // g(x, z) in R^3
-  problem.AddResidualBlock(new ParameterIgnoringCostFunction<2, 3, 2, 4>,
-                           nullptr,
-                           x, z);
+  problem.AddResidualBlock(
+      new ParameterIgnoringCostFunction<2, 3, 2, 4>, nullptr, x, z);
 
   // h(y, z) in R^4
-  problem.AddResidualBlock(new ParameterIgnoringCostFunction<3, 4, 3, 4>,
-                           nullptr,
-                           y, z);
+  problem.AddResidualBlock(
+      new ParameterIgnoringCostFunction<3, 4, 3, 4>, nullptr, y, z);
 
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     9, 9,
@@ -385,12 +390,13 @@
                       0, 0,    3, 6, 9,    3, 6, 9, 12
     }
   };
+  // clang-format on
   CheckAllEvaluationCombinations(expected);
 }
 
 TEST_P(EvaluatorTest, MultipleResidualsWithLocalParameterizations) {
   // Add the parameters in explicit order to force the ordering in the program.
-  problem.AddParameterBlock(x,  2);
+  problem.AddParameterBlock(x, 2);
 
   // Fix y's first dimension.
   vector<int> y_fixed;
@@ -403,20 +409,18 @@
   problem.AddParameterBlock(z, 4, new SubsetParameterization(4, z_fixed));
 
   // f(x, y) in R^2
-  problem.AddResidualBlock(new ParameterIgnoringCostFunction<1, 2, 2, 3>,
-                           nullptr,
-                           x, y);
+  problem.AddResidualBlock(
+      new ParameterIgnoringCostFunction<1, 2, 2, 3>, nullptr, x, y);
 
   // g(x, z) in R^3
-  problem.AddResidualBlock(new ParameterIgnoringCostFunction<2, 3, 2, 4>,
-                           nullptr,
-                           x, z);
+  problem.AddResidualBlock(
+      new ParameterIgnoringCostFunction<2, 3, 2, 4>, nullptr, x, z);
 
   // h(y, z) in R^4
-  problem.AddResidualBlock(new ParameterIgnoringCostFunction<3, 4, 3, 4>,
-                           nullptr,
-                           y, z);
+  problem.AddResidualBlock(
+      new ParameterIgnoringCostFunction<3, 4, 3, 4>, nullptr, y, z);
 
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     9, 7,
@@ -448,6 +452,7 @@
                       0, 0,    6, 9,    3, 9, 12
     }
   };
+  // clang-format on
   CheckAllEvaluationCombinations(expected);
 }
 
@@ -458,24 +463,21 @@
   double z[4];
 
   // Add the parameters in explicit order to force the ordering in the program.
-  problem.AddParameterBlock(x,  2);
-  problem.AddParameterBlock(y,  3);
-  problem.AddParameterBlock(z,  4);
+  problem.AddParameterBlock(x, 2);
+  problem.AddParameterBlock(y, 3);
+  problem.AddParameterBlock(z, 4);
 
   // f(x, y) in R^2
- problem.AddResidualBlock(new ParameterIgnoringCostFunction<1, 2, 2, 3>,
-                          nullptr,
-                          x, y);
+  problem.AddResidualBlock(
+      new ParameterIgnoringCostFunction<1, 2, 2, 3>, nullptr, x, y);
 
   // g(x, z) in R^3
- problem.AddResidualBlock(new ParameterIgnoringCostFunction<2, 3, 2, 4>,
-                          nullptr,
-                          x, z);
+  problem.AddResidualBlock(
+      new ParameterIgnoringCostFunction<2, 3, 2, 4>, nullptr, x, z);
 
   // h(y, z) in R^4
-  problem.AddResidualBlock(new ParameterIgnoringCostFunction<3, 4, 3, 4>,
-                           nullptr,
-                           y, z);
+  problem.AddResidualBlock(
+      new ParameterIgnoringCostFunction<3, 4, 3, 4>, nullptr, y, z);
 
   // For this test, "z" is constant.
   problem.SetParameterBlockConstant(z);
@@ -493,6 +495,7 @@
   ParameterBlock* parameter_block_z = parameter_blocks->back();
   parameter_blocks->pop_back();
 
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     9, 5,
@@ -523,6 +526,7 @@
                       0, 0,    3, 6, 9
     }
   };
+  // clang-format on
   CheckAllEvaluationCombinations(expected);
 
   // Restore parameter block z, so it will get freed in a consistent way.
@@ -554,7 +558,7 @@
 //
 // Try all values of num_eliminate_blocks that make sense given that in the
 // tests a maximum of 4 parameter blocks are present.
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     LinearSolvers,
     EvaluatorTest,
     ::testing::Values(EvaluatorTestOptions(DENSE_QR, 0),
@@ -580,9 +584,9 @@
 // state changes.
 class ParameterSensitiveCostFunction : public SizedCostFunction<2, 2> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     double x1 = parameters[0][0];
     double x2 = parameters[0][1];
     residuals[0] = x1 * x1;
diff --git a/internal/ceres/evaluator_test_utils.cc b/internal/ceres/evaluator_test_utils.cc
index 36dc21c..25801db 100644
--- a/internal/ceres/evaluator_test_utils.cc
+++ b/internal/ceres/evaluator_test_utils.cc
@@ -30,6 +30,7 @@
 //         sameeragarwal@google.com (Sameer Agarwal)
 
 #include "ceres/evaluator_test_utils.h"
+
 #include "ceres/internal/eigen.h"
 #include "gtest/gtest.h"
 
@@ -51,37 +52,39 @@
   if (expected_residuals != NULL) {
     ConstVectorRef expected_residuals_vector(expected_residuals,
                                              expected_num_rows);
-    ConstVectorRef actual_residuals_vector(actual_residuals,
-                                           expected_num_rows);
-    EXPECT_TRUE((actual_residuals_vector.array() ==
-                 expected_residuals_vector.array()).all())
-        << "Actual:\n" << actual_residuals_vector
-        << "\nExpected:\n" << expected_residuals_vector;
+    ConstVectorRef actual_residuals_vector(actual_residuals, expected_num_rows);
+    EXPECT_TRUE(
+        (actual_residuals_vector.array() == expected_residuals_vector.array())
+            .all())
+        << "Actual:\n"
+        << actual_residuals_vector << "\nExpected:\n"
+        << expected_residuals_vector;
   }
 
   if (expected_gradient != NULL) {
     ConstVectorRef expected_gradient_vector(expected_gradient,
                                             expected_num_cols);
-    ConstVectorRef actual_gradient_vector(actual_gradient,
-                                            expected_num_cols);
+    ConstVectorRef actual_gradient_vector(actual_gradient, expected_num_cols);
 
-    EXPECT_TRUE((actual_gradient_vector.array() ==
-                 expected_gradient_vector.array()).all())
-        << "Actual:\n" << actual_gradient_vector.transpose()
-        << "\nExpected:\n" << expected_gradient_vector.transpose();
+    EXPECT_TRUE(
+        (actual_gradient_vector.array() == expected_gradient_vector.array())
+            .all())
+        << "Actual:\n"
+        << actual_gradient_vector.transpose() << "\nExpected:\n"
+        << expected_gradient_vector.transpose();
   }
 
   if (expected_jacobian != NULL) {
-    ConstMatrixRef expected_jacobian_matrix(expected_jacobian,
-                                            expected_num_rows,
-                                            expected_num_cols);
-    ConstMatrixRef actual_jacobian_matrix(actual_jacobian,
-                                          expected_num_rows,
-                                          expected_num_cols);
-    EXPECT_TRUE((actual_jacobian_matrix.array() ==
-                 expected_jacobian_matrix.array()).all())
-        << "Actual:\n" << actual_jacobian_matrix
-        << "\nExpected:\n" << expected_jacobian_matrix;
+    ConstMatrixRef expected_jacobian_matrix(
+        expected_jacobian, expected_num_rows, expected_num_cols);
+    ConstMatrixRef actual_jacobian_matrix(
+        actual_jacobian, expected_num_rows, expected_num_cols);
+    EXPECT_TRUE(
+        (actual_jacobian_matrix.array() == expected_jacobian_matrix.array())
+            .all())
+        << "Actual:\n"
+        << actual_jacobian_matrix << "\nExpected:\n"
+        << expected_jacobian_matrix;
   }
 }
 
diff --git a/internal/ceres/evaluator_test_utils.h b/internal/ceres/evaluator_test_utils.h
index 7401f04..d47b6fa 100644
--- a/internal/ceres/evaluator_test_utils.h
+++ b/internal/ceres/evaluator_test_utils.h
@@ -31,6 +31,8 @@
 //
 // Test utils used for evaluation testing.
 
+#include "ceres/internal/port.h"
+
 namespace ceres {
 namespace internal {
 
@@ -45,16 +47,16 @@
 };
 
 // Compare two evaluations.
-void CompareEvaluations(int expected_num_rows,
-                        int expected_num_cols,
-                        double expected_cost,
-                        const double* expected_residuals,
-                        const double* expected_gradient,
-                        const double* expected_jacobian,
-                        const double actual_cost,
-                        const double* actual_residuals,
-                        const double* actual_gradient,
-                        const double* actual_jacobian);
+CERES_EXPORT_INTERNAL void CompareEvaluations(int expected_num_rows,
+                                              int expected_num_cols,
+                                              double expected_cost,
+                                              const double* expected_residuals,
+                                              const double* expected_gradient,
+                                              const double* expected_jacobian,
+                                              const double actual_cost,
+                                              const double* actual_residuals,
+                                              const double* actual_gradient,
+                                              const double* actual_jacobian);
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/file.cc b/internal/ceres/file.cc
index c95a44d..94f2135 100644
--- a/internal/ceres/file.cc
+++ b/internal/ceres/file.cc
@@ -33,6 +33,7 @@
 #include "ceres/file.h"
 
 #include <cstdio>
+
 #include "glog/logging.h"
 
 namespace ceres {
@@ -40,7 +41,7 @@
 
 using std::string;
 
-void WriteStringToFileOrDie(const string &data, const string &filename) {
+void WriteStringToFileOrDie(const string& data, const string& filename) {
   FILE* file_descriptor = fopen(filename.c_str(), "wb");
   if (!file_descriptor) {
     LOG(FATAL) << "Couldn't write to file: " << filename;
@@ -49,7 +50,7 @@
   fclose(file_descriptor);
 }
 
-void ReadFileToStringOrDie(const string &filename, string *data) {
+void ReadFileToStringOrDie(const string& filename, string* data) {
   FILE* file_descriptor = fopen(filename.c_str(), "r");
 
   if (!file_descriptor) {
@@ -63,10 +64,8 @@
 
   // Read the data.
   fseek(file_descriptor, 0L, SEEK_SET);
-  int num_read = fread(&((*data)[0]),
-                       sizeof((*data)[0]),
-                       num_bytes,
-                       file_descriptor);
+  int num_read =
+      fread(&((*data)[0]), sizeof((*data)[0]), num_bytes, file_descriptor);
   if (num_read != num_bytes) {
     LOG(FATAL) << "Couldn't read all of " << filename
                << "expected bytes: " << num_bytes * sizeof((*data)[0])
@@ -77,9 +76,9 @@
 
 string JoinPath(const string& dirname, const string& basename) {
 #ifdef _WIN32
-    static const char separator = '\\';
+  static const char separator = '\\';
 #else
-    static const char separator = '/';
+  static const char separator = '/';
 #endif  // _WIN32
 
   if ((!basename.empty() && basename[0] == separator) || dirname.empty()) {
diff --git a/internal/ceres/file.h b/internal/ceres/file.h
index 219b459..c0015df 100644
--- a/internal/ceres/file.h
+++ b/internal/ceres/file.h
@@ -34,18 +34,20 @@
 #define CERES_INTERNAL_FILE_H_
 
 #include <string>
+
 #include "ceres/internal/port.h"
 
 namespace ceres {
 namespace internal {
 
-void WriteStringToFileOrDie(const std::string &data,
-                            const std::string &filename);
-void ReadFileToStringOrDie(const std::string &filename, std::string *data);
+void WriteStringToFileOrDie(const std::string& data,
+                            const std::string& filename);
+void ReadFileToStringOrDie(const std::string& filename, std::string* data);
 
 // Join two path components, adding a slash if necessary.  If basename is an
 // absolute path then JoinPath ignores dirname and simply returns basename.
-std::string JoinPath(const std::string& dirname, const std::string& basename);
+CERES_EXPORT_INTERNAL std::string JoinPath(const std::string& dirname,
+                                           const std::string& basename);
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/fixed_array_test.cc b/internal/ceres/fixed_array_test.cc
new file mode 100644
index 0000000..d418786
--- /dev/null
+++ b/internal/ceres/fixed_array_test.cc
@@ -0,0 +1,861 @@
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "ceres/internal/fixed_array.h"
+
+#include <stdio.h>
+
+#include <cstring>
+#include <list>
+#include <memory>
+#include <numeric>
+#include <scoped_allocator>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using ::testing::ElementsAreArray;
+
+namespace {
+
+// CERES_INTERNAL_ARRAYSIZE()
+//
+// Returns the number of elements in an array as a compile-time constant, which
+// can be used in defining new arrays. If you use this macro on a pointer by
+// mistake, you will get a compile-time error.
+#define CERES_INTERNAL_ARRAYSIZE(array) (sizeof(ArraySizeHelper(array)))
+
+// Note: this internal template function declaration is used by
+// CERES_INTERNAL_ARRAYSIZE. The function doesn't need a definition, as we only
+// use its type.
+template <typename T, size_t N>
+auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N];
+
+// Helper routine to determine if a ceres::internal::FixedArray used stack
+// allocation.
+template <typename ArrayType>
+static bool IsOnStack(const ArrayType& a) {
+  return a.size() <= ArrayType::inline_elements;
+}
+
+class ConstructionTester {
+ public:
+  ConstructionTester() : self_ptr_(this), value_(0) { constructions++; }
+  ~ConstructionTester() {
+    assert(self_ptr_ == this);
+    self_ptr_ = nullptr;
+    destructions++;
+  }
+
+  // These are incremented as elements are constructed and destructed so we can
+  // be sure all elements are properly cleaned up.
+  static int constructions;
+  static int destructions;
+
+  void CheckConstructed() { assert(self_ptr_ == this); }
+
+  void set(int value) { value_ = value; }
+  int get() { return value_; }
+
+ private:
+  // self_ptr_ should always point to 'this' -- that's how we can be sure the
+  // constructor has been called.
+  ConstructionTester* self_ptr_;
+  int value_;
+};
+
+int ConstructionTester::constructions = 0;
+int ConstructionTester::destructions = 0;
+
+// ThreeInts will initialize its three ints to the value stored in
+// ThreeInts::counter. The constructor increments counter so that each object
+// in an array of ThreeInts will have different values.
+class ThreeInts {
+ public:
+  ThreeInts() {
+    x_ = counter;
+    y_ = counter;
+    z_ = counter;
+    ++counter;
+  }
+
+  static int counter;
+
+  int x_, y_, z_;
+};
+
+int ThreeInts::counter = 0;
+
+TEST(FixedArrayTest, CopyCtor) {
+  ceres::internal::FixedArray<int, 10> on_stack(5);
+  std::iota(on_stack.begin(), on_stack.end(), 0);
+  ceres::internal::FixedArray<int, 10> stack_copy = on_stack;
+  EXPECT_THAT(stack_copy, ElementsAreArray(on_stack));
+  EXPECT_TRUE(IsOnStack(stack_copy));
+
+  ceres::internal::FixedArray<int, 10> allocated(15);
+  std::iota(allocated.begin(), allocated.end(), 0);
+  ceres::internal::FixedArray<int, 10> alloced_copy = allocated;
+  EXPECT_THAT(alloced_copy, ElementsAreArray(allocated));
+  EXPECT_FALSE(IsOnStack(alloced_copy));
+}
+
+TEST(FixedArrayTest, MoveCtor) {
+  ceres::internal::FixedArray<std::unique_ptr<int>, 10> on_stack(5);
+  for (int i = 0; i < 5; ++i) {
+    on_stack[i] = std::unique_ptr<int>(new int(i));
+  }
+
+  ceres::internal::FixedArray<std::unique_ptr<int>, 10> stack_copy =
+      std::move(on_stack);
+  for (int i = 0; i < 5; ++i) EXPECT_EQ(*(stack_copy[i]), i);
+  EXPECT_EQ(stack_copy.size(), on_stack.size());
+
+  ceres::internal::FixedArray<std::unique_ptr<int>, 10> allocated(15);
+  for (int i = 0; i < 15; ++i) {
+    allocated[i] = std::unique_ptr<int>(new int(i));
+  }
+
+  ceres::internal::FixedArray<std::unique_ptr<int>, 10> alloced_copy =
+      std::move(allocated);
+  for (int i = 0; i < 15; ++i) EXPECT_EQ(*(alloced_copy[i]), i);
+  EXPECT_EQ(allocated.size(), alloced_copy.size());
+}
+
+TEST(FixedArrayTest, SmallObjects) {
+  // Small object arrays
+  {
+    // Short arrays should be on the stack
+    ceres::internal::FixedArray<int> array(4);
+    EXPECT_TRUE(IsOnStack(array));
+  }
+
+  {
+    // Large arrays should be on the heap
+    ceres::internal::FixedArray<int> array(1048576);
+    EXPECT_FALSE(IsOnStack(array));
+  }
+
+  {
+    // Arrays of <= default size should be on the stack
+    ceres::internal::FixedArray<int, 100> array(100);
+    EXPECT_TRUE(IsOnStack(array));
+  }
+
+  {
+    // Arrays of > default size should be on the heap
+    ceres::internal::FixedArray<int, 100> array(101);
+    EXPECT_FALSE(IsOnStack(array));
+  }
+
+  {
+    // Arrays with different size elements should use approximately
+    // same amount of stack space
+    ceres::internal::FixedArray<int> array1(0);
+    ceres::internal::FixedArray<char> array2(0);
+    EXPECT_LE(sizeof(array1), sizeof(array2) + 100);
+    EXPECT_LE(sizeof(array2), sizeof(array1) + 100);
+  }
+
+  {
+    // Ensure that vectors are properly constructed inside a fixed array.
+    ceres::internal::FixedArray<std::vector<int>> array(2);
+    EXPECT_EQ(0, array[0].size());
+    EXPECT_EQ(0, array[1].size());
+  }
+
+  {
+    // Regardless of ceres::internal::FixedArray implementation, check that a
+    // type with a low alignment requirement and a non power-of-two size is
+    // initialized correctly.
+    ThreeInts::counter = 1;
+    ceres::internal::FixedArray<ThreeInts> array(2);
+    EXPECT_EQ(1, array[0].x_);
+    EXPECT_EQ(1, array[0].y_);
+    EXPECT_EQ(1, array[0].z_);
+    EXPECT_EQ(2, array[1].x_);
+    EXPECT_EQ(2, array[1].y_);
+    EXPECT_EQ(2, array[1].z_);
+  }
+}
+
+TEST(FixedArrayRelationalsTest, EqualArrays) {
+  for (int i = 0; i < 10; ++i) {
+    ceres::internal::FixedArray<int, 5> a1(i);
+    std::iota(a1.begin(), a1.end(), 0);
+    ceres::internal::FixedArray<int, 5> a2(a1.begin(), a1.end());
+
+    EXPECT_TRUE(a1 == a2);
+    EXPECT_FALSE(a1 != a2);
+    EXPECT_TRUE(a2 == a1);
+    EXPECT_FALSE(a2 != a1);
+    EXPECT_FALSE(a1 < a2);
+    EXPECT_FALSE(a1 > a2);
+    EXPECT_FALSE(a2 < a1);
+    EXPECT_FALSE(a2 > a1);
+    EXPECT_TRUE(a1 <= a2);
+    EXPECT_TRUE(a1 >= a2);
+    EXPECT_TRUE(a2 <= a1);
+    EXPECT_TRUE(a2 >= a1);
+  }
+}
+
+TEST(FixedArrayRelationalsTest, UnequalArrays) {
+  for (int i = 1; i < 10; ++i) {
+    ceres::internal::FixedArray<int, 5> a1(i);
+    std::iota(a1.begin(), a1.end(), 0);
+    ceres::internal::FixedArray<int, 5> a2(a1.begin(), a1.end());
+    --a2[i / 2];
+
+    EXPECT_FALSE(a1 == a2);
+    EXPECT_TRUE(a1 != a2);
+    EXPECT_FALSE(a2 == a1);
+    EXPECT_TRUE(a2 != a1);
+    EXPECT_FALSE(a1 < a2);
+    EXPECT_TRUE(a1 > a2);
+    EXPECT_TRUE(a2 < a1);
+    EXPECT_FALSE(a2 > a1);
+    EXPECT_FALSE(a1 <= a2);
+    EXPECT_TRUE(a1 >= a2);
+    EXPECT_TRUE(a2 <= a1);
+    EXPECT_FALSE(a2 >= a1);
+  }
+}
+
+template <int stack_elements>
+static void TestArray(int n) {
+  SCOPED_TRACE(n);
+  SCOPED_TRACE(stack_elements);
+  ConstructionTester::constructions = 0;
+  ConstructionTester::destructions = 0;
+  {
+    ceres::internal::FixedArray<ConstructionTester, stack_elements> array(n);
+
+    EXPECT_THAT(array.size(), n);
+    EXPECT_THAT(array.memsize(), sizeof(ConstructionTester) * n);
+    EXPECT_THAT(array.begin() + n, array.end());
+
+    // Check that all elements were constructed
+    for (int i = 0; i < n; i++) {
+      array[i].CheckConstructed();
+    }
+    // Check that no other elements were constructed
+    EXPECT_THAT(ConstructionTester::constructions, n);
+
+    // Test operator[]
+    for (int i = 0; i < n; i++) {
+      array[i].set(i);
+    }
+    for (int i = 0; i < n; i++) {
+      EXPECT_THAT(array[i].get(), i);
+      EXPECT_THAT(array.data()[i].get(), i);
+    }
+
+    // Test data()
+    for (int i = 0; i < n; i++) {
+      array.data()[i].set(i + 1);
+    }
+    for (int i = 0; i < n; i++) {
+      EXPECT_THAT(array[i].get(), i + 1);
+      EXPECT_THAT(array.data()[i].get(), i + 1);
+    }
+  }  // Close scope containing 'array'.
+
+  // Check that all constructed elements were destructed.
+  EXPECT_EQ(ConstructionTester::constructions,
+            ConstructionTester::destructions);
+}
+
+template <int elements_per_inner_array, int inline_elements>
+static void TestArrayOfArrays(int n) {
+  SCOPED_TRACE(n);
+  SCOPED_TRACE(inline_elements);
+  SCOPED_TRACE(elements_per_inner_array);
+  ConstructionTester::constructions = 0;
+  ConstructionTester::destructions = 0;
+  {
+    using InnerArray = ConstructionTester[elements_per_inner_array];
+    // Heap-allocate the FixedArray to avoid blowing the stack frame.
+    auto array_ptr = std::unique_ptr<
+        ceres::internal::FixedArray<InnerArray, inline_elements>>(
+        new ceres::internal::FixedArray<InnerArray, inline_elements>(n));
+    auto& array = *array_ptr;
+
+    ASSERT_EQ(array.size(), n);
+    ASSERT_EQ(array.memsize(),
+              sizeof(ConstructionTester) * elements_per_inner_array * n);
+    ASSERT_EQ(array.begin() + n, array.end());
+
+    // Check that all elements were constructed
+    for (int i = 0; i < n; i++) {
+      for (int j = 0; j < elements_per_inner_array; j++) {
+        (array[i])[j].CheckConstructed();
+      }
+    }
+    // Check that no other elements were constructed
+    ASSERT_EQ(ConstructionTester::constructions, n * elements_per_inner_array);
+
+    // Test operator[]
+    for (int i = 0; i < n; i++) {
+      for (int j = 0; j < elements_per_inner_array; j++) {
+        (array[i])[j].set(i * elements_per_inner_array + j);
+      }
+    }
+    for (int i = 0; i < n; i++) {
+      for (int j = 0; j < elements_per_inner_array; j++) {
+        ASSERT_EQ((array[i])[j].get(), i * elements_per_inner_array + j);
+        ASSERT_EQ((array.data()[i])[j].get(), i * elements_per_inner_array + j);
+      }
+    }
+
+    // Test data()
+    for (int i = 0; i < n; i++) {
+      for (int j = 0; j < elements_per_inner_array; j++) {
+        (array.data()[i])[j].set((i + 1) * elements_per_inner_array + j);
+      }
+    }
+    for (int i = 0; i < n; i++) {
+      for (int j = 0; j < elements_per_inner_array; j++) {
+        ASSERT_EQ((array[i])[j].get(), (i + 1) * elements_per_inner_array + j);
+        ASSERT_EQ((array.data()[i])[j].get(),
+                  (i + 1) * elements_per_inner_array + j);
+      }
+    }
+  }  // Close scope containing 'array'.
+
+  // Check that all constructed elements were destructed.
+  EXPECT_EQ(ConstructionTester::constructions,
+            ConstructionTester::destructions);
+}
+
+TEST(IteratorConstructorTest, NonInline) {
+  int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
+  ceres::internal::FixedArray<int, CERES_INTERNAL_ARRAYSIZE(kInput) - 1> const
+      fixed(kInput, kInput + CERES_INTERNAL_ARRAYSIZE(kInput));
+  ASSERT_EQ(CERES_INTERNAL_ARRAYSIZE(kInput), fixed.size());
+  for (size_t i = 0; i < CERES_INTERNAL_ARRAYSIZE(kInput); ++i) {
+    ASSERT_EQ(kInput[i], fixed[i]);
+  }
+}
+
+TEST(IteratorConstructorTest, Inline) {
+  int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
+  ceres::internal::FixedArray<int, CERES_INTERNAL_ARRAYSIZE(kInput)> const
+      fixed(kInput, kInput + CERES_INTERNAL_ARRAYSIZE(kInput));
+  ASSERT_EQ(CERES_INTERNAL_ARRAYSIZE(kInput), fixed.size());
+  for (size_t i = 0; i < CERES_INTERNAL_ARRAYSIZE(kInput); ++i) {
+    ASSERT_EQ(kInput[i], fixed[i]);
+  }
+}
+
+TEST(IteratorConstructorTest, NonPod) {
+  char const* kInput[] = {
+      "red", "orange", "yellow", "green", "blue", "indigo", "violet"};
+  ceres::internal::FixedArray<std::string> const fixed(
+      kInput, kInput + CERES_INTERNAL_ARRAYSIZE(kInput));
+  ASSERT_EQ(CERES_INTERNAL_ARRAYSIZE(kInput), fixed.size());
+  for (size_t i = 0; i < CERES_INTERNAL_ARRAYSIZE(kInput); ++i) {
+    ASSERT_EQ(kInput[i], fixed[i]);
+  }
+}
+
+TEST(IteratorConstructorTest, FromEmptyVector) {
+  std::vector<int> const empty;
+  ceres::internal::FixedArray<int> const fixed(empty.begin(), empty.end());
+  EXPECT_EQ(0, fixed.size());
+  EXPECT_EQ(empty.size(), fixed.size());
+}
+
+TEST(IteratorConstructorTest, FromNonEmptyVector) {
+  int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
+  std::vector<int> const items(kInput,
+                               kInput + CERES_INTERNAL_ARRAYSIZE(kInput));
+  ceres::internal::FixedArray<int> const fixed(items.begin(), items.end());
+  ASSERT_EQ(items.size(), fixed.size());
+  for (size_t i = 0; i < items.size(); ++i) {
+    ASSERT_EQ(items[i], fixed[i]);
+  }
+}
+
+TEST(IteratorConstructorTest, FromBidirectionalIteratorRange) {
+  int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
+  std::list<int> const items(kInput, kInput + CERES_INTERNAL_ARRAYSIZE(kInput));
+  ceres::internal::FixedArray<int> const fixed(items.begin(), items.end());
+  EXPECT_THAT(fixed, testing::ElementsAreArray(kInput));
+}
+
+TEST(InitListConstructorTest, InitListConstruction) {
+  ceres::internal::FixedArray<int> fixed = {1, 2, 3};
+  EXPECT_THAT(fixed, testing::ElementsAreArray({1, 2, 3}));
+}
+
+TEST(FillConstructorTest, NonEmptyArrays) {
+  ceres::internal::FixedArray<int> stack_array(4, 1);
+  EXPECT_THAT(stack_array, testing::ElementsAreArray({1, 1, 1, 1}));
+
+  ceres::internal::FixedArray<int, 0> heap_array(4, 1);
+  EXPECT_THAT(stack_array, testing::ElementsAreArray({1, 1, 1, 1}));
+}
+
+TEST(FillConstructorTest, EmptyArray) {
+  ceres::internal::FixedArray<int> empty_fill(0, 1);
+  ceres::internal::FixedArray<int> empty_size(0);
+  EXPECT_EQ(empty_fill, empty_size);
+}
+
+TEST(FillConstructorTest, NotTriviallyCopyable) {
+  std::string str = "abcd";
+  ceres::internal::FixedArray<std::string> strings = {str, str, str, str};
+
+  ceres::internal::FixedArray<std::string> array(4, str);
+  EXPECT_EQ(array, strings);
+}
+
+TEST(FillConstructorTest, Disambiguation) {
+  ceres::internal::FixedArray<size_t> a(1, 2);
+  EXPECT_THAT(a, testing::ElementsAre(2));
+}
+
+TEST(FixedArrayTest, ManySizedArrays) {
+  std::vector<int> sizes;
+  for (int i = 1; i < 100; i++) sizes.push_back(i);
+  for (int i = 100; i <= 1000; i += 100) sizes.push_back(i);
+  for (int n : sizes) {
+    TestArray<0>(n);
+    TestArray<1>(n);
+    TestArray<64>(n);
+    TestArray<1000>(n);
+  }
+}
+
+TEST(FixedArrayTest, ManySizedArraysOfArraysOf1) {
+  for (int n = 1; n < 1000; n++) {
+    ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 0>(n)));
+    ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 1>(n)));
+    ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 64>(n)));
+    ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 1000>(n)));
+  }
+}
+
+TEST(FixedArrayTest, ManySizedArraysOfArraysOf2) {
+  for (int n = 1; n < 1000; n++) {
+    TestArrayOfArrays<2, 0>(n);
+    TestArrayOfArrays<2, 1>(n);
+    TestArrayOfArrays<2, 64>(n);
+    TestArrayOfArrays<2, 1000>(n);
+  }
+}
+
+// If value_type is put inside of a struct container,
+// we might evoke this error in a hardened build unless data() is carefully
+// written, so check on that.
+//     error: call to int __builtin___sprintf_chk(etc...)
+//     will always overflow destination buffer [-Werror]
+TEST(FixedArrayTest, AvoidParanoidDiagnostics) {
+  ceres::internal::FixedArray<char, 32> buf(32);
+  sprintf(buf.data(), "foo");  // NOLINT(runtime/printf)
+}
+
+TEST(FixedArrayTest, TooBigInlinedSpace) {
+  struct TooBig {
+    char c[1 << 20];
+  };  // too big for even one on the stack
+
+  // Simulate the data members of ceres::internal::FixedArray, a pointer and a
+  // size_t.
+  struct Data {
+    std::tuple<size_t, std::allocator<double>> size_alloc_;
+    TooBig* p;
+  };
+
+  // Make sure TooBig objects are not inlined for 0 or default size.
+  static_assert(
+      sizeof(ceres::internal::FixedArray<TooBig, 0>) == sizeof(Data),
+      "0-sized ceres::internal::FixedArray should have same size as Data.");
+  static_assert(
+      alignof(ceres::internal::FixedArray<TooBig, 0>) == alignof(Data),
+      "0-sized ceres::internal::FixedArray should have same alignment as "
+      "Data.");
+  static_assert(sizeof(ceres::internal::FixedArray<TooBig>) == sizeof(Data),
+                "default-sized ceres::internal::FixedArray should have same "
+                "size as Data");
+  static_assert(alignof(ceres::internal::FixedArray<TooBig>) == alignof(Data),
+                "default-sized ceres::internal::FixedArray should have same "
+                "alignment as Data.");
+}
+
+// PickyDelete EXPECTs its class-scope deallocation funcs are unused.
+struct PickyDelete {
+  PickyDelete() {}
+  ~PickyDelete() {}
+  void operator delete(void* p) {
+    EXPECT_TRUE(false) << __FUNCTION__;
+    ::operator delete(p);
+  }
+  void operator delete[](void* p) {
+    EXPECT_TRUE(false) << __FUNCTION__;
+    ::operator delete[](p);
+  }
+};
+
+TEST(FixedArrayTest, UsesGlobalAlloc) {
+  ceres::internal::FixedArray<PickyDelete, 0> a(5);
+}
+
+TEST(FixedArrayTest, Data) {
+  static const int kInput[] = {2, 3, 5, 7, 11, 13, 17};
+  ceres::internal::FixedArray<int> fa(std::begin(kInput), std::end(kInput));
+  EXPECT_EQ(fa.data(), &*fa.begin());
+  EXPECT_EQ(fa.data(), &fa[0]);
+
+  const ceres::internal::FixedArray<int>& cfa = fa;
+  EXPECT_EQ(cfa.data(), &*cfa.begin());
+  EXPECT_EQ(cfa.data(), &cfa[0]);
+}
+
+TEST(FixedArrayTest, Empty) {
+  ceres::internal::FixedArray<int> empty(0);
+  ceres::internal::FixedArray<int> inline_filled(1);
+  ceres::internal::FixedArray<int, 0> heap_filled(1);
+  EXPECT_TRUE(empty.empty());
+  EXPECT_FALSE(inline_filled.empty());
+  EXPECT_FALSE(heap_filled.empty());
+}
+
+TEST(FixedArrayTest, FrontAndBack) {
+  ceres::internal::FixedArray<int, 3 * sizeof(int)> inlined = {1, 2, 3};
+  EXPECT_EQ(inlined.front(), 1);
+  EXPECT_EQ(inlined.back(), 3);
+
+  ceres::internal::FixedArray<int, 0> allocated = {1, 2, 3};
+  EXPECT_EQ(allocated.front(), 1);
+  EXPECT_EQ(allocated.back(), 3);
+
+  ceres::internal::FixedArray<int> one_element = {1};
+  EXPECT_EQ(one_element.front(), one_element.back());
+}
+
+TEST(FixedArrayTest, ReverseIteratorInlined) {
+  ceres::internal::FixedArray<int, 5 * sizeof(int)> a = {0, 1, 2, 3, 4};
+
+  int counter = 5;
+  for (ceres::internal::FixedArray<int>::reverse_iterator iter = a.rbegin();
+       iter != a.rend();
+       ++iter) {
+    counter--;
+    EXPECT_EQ(counter, *iter);
+  }
+  EXPECT_EQ(counter, 0);
+
+  counter = 5;
+  for (ceres::internal::FixedArray<int>::const_reverse_iterator iter =
+           a.rbegin();
+       iter != a.rend();
+       ++iter) {
+    counter--;
+    EXPECT_EQ(counter, *iter);
+  }
+  EXPECT_EQ(counter, 0);
+
+  counter = 5;
+  for (auto iter = a.crbegin(); iter != a.crend(); ++iter) {
+    counter--;
+    EXPECT_EQ(counter, *iter);
+  }
+  EXPECT_EQ(counter, 0);
+}
+
+TEST(FixedArrayTest, ReverseIteratorAllocated) {
+  ceres::internal::FixedArray<int, 0> a = {0, 1, 2, 3, 4};
+
+  int counter = 5;
+  for (ceres::internal::FixedArray<int>::reverse_iterator iter = a.rbegin();
+       iter != a.rend();
+       ++iter) {
+    counter--;
+    EXPECT_EQ(counter, *iter);
+  }
+  EXPECT_EQ(counter, 0);
+
+  counter = 5;
+  for (ceres::internal::FixedArray<int>::const_reverse_iterator iter =
+           a.rbegin();
+       iter != a.rend();
+       ++iter) {
+    counter--;
+    EXPECT_EQ(counter, *iter);
+  }
+  EXPECT_EQ(counter, 0);
+
+  counter = 5;
+  for (auto iter = a.crbegin(); iter != a.crend(); ++iter) {
+    counter--;
+    EXPECT_EQ(counter, *iter);
+  }
+  EXPECT_EQ(counter, 0);
+}
+
+TEST(FixedArrayTest, Fill) {
+  ceres::internal::FixedArray<int, 5 * sizeof(int)> inlined(5);
+  int fill_val = 42;
+  inlined.fill(fill_val);
+  for (int i : inlined) EXPECT_EQ(i, fill_val);
+
+  ceres::internal::FixedArray<int, 0> allocated(5);
+  allocated.fill(fill_val);
+  for (int i : allocated) EXPECT_EQ(i, fill_val);
+
+  // It doesn't do anything, just make sure this compiles.
+  ceres::internal::FixedArray<int> empty(0);
+  empty.fill(fill_val);
+}
+
+// TODO(johnsoncj): Investigate InlinedStorage default initialization in GCC 4.x
+#ifndef __GNUC__
+TEST(FixedArrayTest, DefaultCtorDoesNotValueInit) {
+  using T = char;
+  constexpr auto capacity = 10;
+  using FixedArrType = ceres::internal::FixedArray<T, capacity>;
+  using FixedArrBuffType =
+      typename std::aligned_storage<sizeof(FixedArrType),
+                                    alignof(FixedArrType)>::type;
+  constexpr auto scrubbed_bits = 0x95;
+  constexpr auto length = capacity / 2;
+
+  FixedArrBuffType buff;
+  std::memset(std::addressof(buff), scrubbed_bits, sizeof(FixedArrBuffType));
+
+  FixedArrType* arr =
+      ::new (static_cast<void*>(std::addressof(buff))) FixedArrType(length);
+  EXPECT_THAT(*arr, testing::Each(scrubbed_bits));
+  arr->~FixedArrType();
+}
+#endif  // __GNUC__
+
+// This is a stateful allocator, but the state lives outside of the
+// allocator (in whatever test is using the allocator). This is odd
+// but helps in tests where the allocator is propagated into nested
+// containers - that chain of allocators uses the same state and is
+// thus easier to query for aggregate allocation information.
+template <typename T>
+class CountingAllocator : public std::allocator<T> {
+ public:
+  using Alloc = std::allocator<T>;
+  using pointer = typename Alloc::pointer;
+  using size_type = typename Alloc::size_type;
+
+  CountingAllocator() : bytes_used_(nullptr), instance_count_(nullptr) {}
+  explicit CountingAllocator(int64_t* b)
+      : bytes_used_(b), instance_count_(nullptr) {}
+  CountingAllocator(int64_t* b, int64_t* a)
+      : bytes_used_(b), instance_count_(a) {}
+
+  template <typename U>
+  explicit CountingAllocator(const CountingAllocator<U>& x)
+      : Alloc(x),
+        bytes_used_(x.bytes_used_),
+        instance_count_(x.instance_count_) {}
+
+  pointer allocate(size_type n, const void* const hint = nullptr) {
+    assert(bytes_used_ != nullptr);
+    *bytes_used_ += n * sizeof(T);
+    return Alloc::allocate(n, hint);
+  }
+
+  void deallocate(pointer p, size_type n) {
+    Alloc::deallocate(p, n);
+    assert(bytes_used_ != nullptr);
+    *bytes_used_ -= n * sizeof(T);
+  }
+
+  template <typename... Args>
+  void construct(pointer p, Args&&... args) {
+    Alloc::construct(p, std::forward<Args>(args)...);
+    if (instance_count_) {
+      *instance_count_ += 1;
+    }
+  }
+
+  void destroy(pointer p) {
+    Alloc::destroy(p);
+    if (instance_count_) {
+      *instance_count_ -= 1;
+    }
+  }
+
+  template <typename U>
+  class rebind {
+   public:
+    using other = CountingAllocator<U>;
+  };
+
+  int64_t* bytes_used_;
+  int64_t* instance_count_;
+};
+
+TEST(AllocatorSupportTest, CountInlineAllocations) {
+  constexpr size_t inlined_size = 4;
+  using Alloc = CountingAllocator<int>;
+  using AllocFxdArr = ceres::internal::FixedArray<int, inlined_size, Alloc>;
+
+  int64_t allocated = 0;
+  int64_t active_instances = 0;
+
+  {
+    const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
+
+    Alloc alloc(&allocated, &active_instances);
+
+    AllocFxdArr arr(ia, ia + inlined_size, alloc);
+    static_cast<void>(arr);
+  }
+
+  EXPECT_EQ(allocated, 0);
+  EXPECT_EQ(active_instances, 0);
+}
+
+TEST(AllocatorSupportTest, CountOutoflineAllocations) {
+  constexpr size_t inlined_size = 4;
+  using Alloc = CountingAllocator<int>;
+  using AllocFxdArr = ceres::internal::FixedArray<int, inlined_size, Alloc>;
+
+  int64_t allocated = 0;
+  int64_t active_instances = 0;
+
+  {
+    const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
+    Alloc alloc(&allocated, &active_instances);
+
+    AllocFxdArr arr(ia, ia + CERES_INTERNAL_ARRAYSIZE(ia), alloc);
+
+    EXPECT_EQ(allocated, arr.size() * sizeof(int));
+    static_cast<void>(arr);
+  }
+
+  EXPECT_EQ(active_instances, 0);
+}
+
+TEST(AllocatorSupportTest, CountCopyInlineAllocations) {
+  constexpr size_t inlined_size = 4;
+  using Alloc = CountingAllocator<int>;
+  using AllocFxdArr = ceres::internal::FixedArray<int, inlined_size, Alloc>;
+
+  int64_t allocated1 = 0;
+  int64_t allocated2 = 0;
+  int64_t active_instances = 0;
+  Alloc alloc(&allocated1, &active_instances);
+  Alloc alloc2(&allocated2, &active_instances);
+
+  {
+    int initial_value = 1;
+
+    AllocFxdArr arr1(inlined_size / 2, initial_value, alloc);
+
+    EXPECT_EQ(allocated1, 0);
+
+    AllocFxdArr arr2(arr1, alloc2);
+
+    EXPECT_EQ(allocated2, 0);
+    static_cast<void>(arr1);
+    static_cast<void>(arr2);
+  }
+
+  EXPECT_EQ(active_instances, 0);
+}
+
+TEST(AllocatorSupportTest, CountCopyOutoflineAllocations) {
+  constexpr size_t inlined_size = 4;
+  using Alloc = CountingAllocator<int>;
+  using AllocFxdArr = ceres::internal::FixedArray<int, inlined_size, Alloc>;
+
+  int64_t allocated1 = 0;
+  int64_t allocated2 = 0;
+  int64_t active_instances = 0;
+  Alloc alloc(&allocated1, &active_instances);
+  Alloc alloc2(&allocated2, &active_instances);
+
+  {
+    int initial_value = 1;
+
+    AllocFxdArr arr1(inlined_size * 2, initial_value, alloc);
+
+    EXPECT_EQ(allocated1, arr1.size() * sizeof(int));
+
+    AllocFxdArr arr2(arr1, alloc2);
+
+    EXPECT_EQ(allocated2, inlined_size * 2 * sizeof(int));
+    static_cast<void>(arr1);
+    static_cast<void>(arr2);
+  }
+
+  EXPECT_EQ(active_instances, 0);
+}
+
+TEST(AllocatorSupportTest, SizeValAllocConstructor) {
+  using testing::AllOf;
+  using testing::Each;
+  using testing::SizeIs;
+
+  constexpr size_t inlined_size = 4;
+  using Alloc = CountingAllocator<int>;
+  using AllocFxdArr = ceres::internal::FixedArray<int, inlined_size, Alloc>;
+
+  {
+    auto len = inlined_size / 2;
+    auto val = 0;
+    int64_t allocated = 0;
+    AllocFxdArr arr(len, val, Alloc(&allocated));
+
+    EXPECT_EQ(allocated, 0);
+    EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0)));
+  }
+
+  {
+    auto len = inlined_size * 2;
+    auto val = 0;
+    int64_t allocated = 0;
+    AllocFxdArr arr(len, val, Alloc(&allocated));
+
+    EXPECT_EQ(allocated, len * sizeof(int));
+    EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0)));
+  }
+}
+
+struct EigenStruct {
+  Eigen::Vector4d data;
+};
+
+static_assert(
+    std::is_same<ceres::internal::FixedArrayDefaultAllocator<double>,
+                 std::allocator<double>>::value,
+    "Double is a trivial type, so std::allocator should be used here.");
+static_assert(
+    std::is_same<ceres::internal::FixedArrayDefaultAllocator<double*>,
+                 std::allocator<double*>>::value,
+    "A pointer is a trivial type, so std::allocator should be used here.");
+static_assert(
+    std::is_same<ceres::internal::FixedArrayDefaultAllocator<Eigen::Matrix4d>,
+                 Eigen::aligned_allocator<Eigen::Matrix4d>>::value,
+    "An Eigen::Matrix4d needs the Eigen::aligned_allocator for proper "
+    "alignment.");
+static_assert(
+    std::is_same<ceres::internal::FixedArrayDefaultAllocator<EigenStruct>,
+                 Eigen::aligned_allocator<EigenStruct>>::value,
+    "A struct containing fixed size Eigen types needs Eigen::aligned_allocator "
+    "for proper alignment.");
+
+}  // namespace
diff --git a/internal/ceres/float_cxsparse.h b/internal/ceres/float_cxsparse.h
index 57fc5e4..9a274c2 100644
--- a/internal/ceres/float_cxsparse.h
+++ b/internal/ceres/float_cxsparse.h
@@ -37,6 +37,7 @@
 #if !defined(CERES_NO_CXSPARSE)
 
 #include <memory>
+
 #include "ceres/sparse_cholesky.h"
 
 namespace ceres {
@@ -46,8 +47,7 @@
 // CXSparse.
 class FloatCXSparseCholesky : public SparseCholesky {
  public:
-  static std::unique_ptr<SparseCholesky> Create(
-      OrderingType ordering_type);
+  static std::unique_ptr<SparseCholesky> Create(OrderingType ordering_type);
 };
 
 }  // namespace internal
diff --git a/internal/ceres/float_suitesparse.h b/internal/ceres/float_suitesparse.h
index ac4d409..c436da4 100644
--- a/internal/ceres/float_suitesparse.h
+++ b/internal/ceres/float_suitesparse.h
@@ -32,9 +32,12 @@
 #define CERES_INTERNAL_FLOAT_SUITESPARSE_H_
 
 // This include must come before any #ifndef check on Ceres compile options.
+// clang-format off
 #include "ceres/internal/port.h"
+// clang-format on
 
 #include <memory>
+
 #include "ceres/sparse_cholesky.h"
 
 #if !defined(CERES_NO_SUITESPARSE)
@@ -46,8 +49,7 @@
 // SuiteSparse.
 class FloatSuiteSparseCholesky : public SparseCholesky {
  public:
-  static std::unique_ptr<SparseCholesky> Create(
-      OrderingType ordering_type);
+  static std::unique_ptr<SparseCholesky> Create(OrderingType ordering_type);
 };
 
 }  // namespace internal
diff --git a/internal/ceres/function_sample.cc b/internal/ceres/function_sample.cc
index 2fd3dbd..3e0ae60 100644
--- a/internal/ceres/function_sample.cc
+++ b/internal/ceres/function_sample.cc
@@ -29,6 +29,7 @@
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
 #include "ceres/function_sample.h"
+
 #include "ceres/stringprintf.h"
 
 namespace ceres {
@@ -64,9 +65,14 @@
       gradient_is_valid(true) {}
 
 std::string FunctionSample::ToDebugString() const {
-  return StringPrintf("[x: %.8e, value: %.8e, gradient: %.8e, "
-                      "value_is_valid: %d, gradient_is_valid: %d]",
-                      x, value, gradient, value_is_valid, gradient_is_valid);
+  return StringPrintf(
+      "[x: %.8e, value: %.8e, gradient: %.8e, "
+      "value_is_valid: %d, gradient_is_valid: %d]",
+      x,
+      value,
+      gradient,
+      value_is_valid,
+      gradient_is_valid);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/function_sample.h b/internal/ceres/function_sample.h
index df79aef..3bcea1b 100644
--- a/internal/ceres/function_sample.h
+++ b/internal/ceres/function_sample.h
@@ -32,7 +32,9 @@
 #define CERES_INTERNAL_FUNCTION_SAMPLE_H_
 
 #include <string>
+
 #include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
 
 namespace ceres {
 namespace internal {
@@ -45,7 +47,7 @@
 // line/direction. FunctionSample contains the information in two
 // ways. Information in the ambient space and information along the
 // direction of search.
-struct FunctionSample {
+struct CERES_EXPORT_INTERNAL FunctionSample {
   FunctionSample();
   FunctionSample(double x, double value);
   FunctionSample(double x, double value, double gradient);
@@ -85,9 +87,6 @@
   bool gradient_is_valid;
 };
 
-
-
-
 }  // namespace internal
 }  // namespace ceres
 
diff --git a/internal/ceres/generate_bundle_adjustment_tests.py b/internal/ceres/generate_bundle_adjustment_tests.py
index a3469eb..7b0caa3 100644
--- a/internal/ceres/generate_bundle_adjustment_tests.py
+++ b/internal/ceres/generate_bundle_adjustment_tests.py
@@ -130,24 +130,22 @@
 
 TEST_F(BundleAdjustmentTest,
        %(test_class_name)s) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = %(num_threads)s;
-   options->linear_solver_type = %(linear_solver)s;
-   options->sparse_linear_algebra_library_type = %(sparse_backend)s;
-   options->preconditioner_type = %(preconditioner)s;
-   if (%(ordering)s) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = %(num_threads)s;
+  options->linear_solver_type = %(linear_solver)s;
+  options->sparse_linear_algebra_library_type = %(sparse_backend)s;
+  options->preconditioner_type = %(preconditioner)s;
+  if (%(ordering)s) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
-%(preprocessor_conditions_end)s
-""")
+%(preprocessor_conditions_end)s""")
 
 def camelcasify(token):
   """Convert capitalized underscore tokens to camel case"""
diff --git a/internal/ceres/generate_template_specializations.py b/internal/ceres/generate_template_specializations.py
index 75c1464..74e46c2 100644
--- a/internal/ceres/generate_template_specializations.py
+++ b/internal/ceres/generate_template_specializations.py
@@ -68,6 +68,7 @@
                    (2, 4, 9),
                    (2, 4, "Eigen::Dynamic"),
                    (2, "Eigen::Dynamic", "Eigen::Dynamic"),
+                   (3, 3, 3),
                    (4, 4, 2),
                    (4, 4, 3),
                    (4, 4, 4),
@@ -100,9 +101,9 @@
     return "%s"
 
   if (len(conditionals) == 1):
-    return " if " + conditionals[0] + "{\n  %s\n }\n"
+    return "  if " + conditionals[0] + " {\n  %s\n  }\n"
 
-  return " if (" + " &&\n     ".join(conditionals) + ") {\n  %s\n }\n"
+  return "  if (" + " &&\n     ".join(conditionals) + ") {\n  %s\n  }\n"
 
 def Specialize(name, data):
   """
@@ -213,10 +214,10 @@
 }  // namespace ceres
 """
 
-QUERY_ACTION = """ *row_block_size = %s;
-   *e_block_size = %s;
-   *f_block_size = %s;
-  return;"""
+QUERY_ACTION = """  *row_block_size = %s;
+    *e_block_size = %s;
+    *f_block_size = %s;
+    return;"""
 
 def GenerateQueryFile():
   """
diff --git a/internal/ceres/generated/.clang-format b/internal/ceres/generated/.clang-format
new file mode 100644
index 0000000..9d15924
--- /dev/null
+++ b/internal/ceres/generated/.clang-format
@@ -0,0 +1,2 @@
+DisableFormat: true
+SortIncludes: false
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_2_2.cc b/internal/ceres/generated/partitioned_matrix_view_2_2_2.cc
index 86ad17b..f5753be 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_2_2.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_2_2.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_2_3.cc b/internal/ceres/generated/partitioned_matrix_view_2_2_3.cc
index 33018d5..a7a9b52 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_2_3.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_2_3.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_2_4.cc b/internal/ceres/generated/partitioned_matrix_view_2_2_4.cc
index a429a54..faf6c4a 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_2_4.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_2_4.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_2_d.cc b/internal/ceres/generated/partitioned_matrix_view_2_2_d.cc
index f6f03ea..92fd4cd 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_2_d.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_2_d.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_3_3.cc b/internal/ceres/generated/partitioned_matrix_view_2_3_3.cc
index 0b73e1a..2df314f 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_3_3.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_3_3.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_3_4.cc b/internal/ceres/generated/partitioned_matrix_view_2_3_4.cc
index bc4a861..ff1ca3e 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_3_4.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_3_4.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_3_6.cc b/internal/ceres/generated/partitioned_matrix_view_2_3_6.cc
index fe8f7dd..5041df9 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_3_6.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_3_6.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_3_9.cc b/internal/ceres/generated/partitioned_matrix_view_2_3_9.cc
index ac493fc..c0b72fe 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_3_9.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_3_9.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_3_d.cc b/internal/ceres/generated/partitioned_matrix_view_2_3_d.cc
index e29efaf..8a3c162 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_3_d.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_3_d.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_4_3.cc b/internal/ceres/generated/partitioned_matrix_view_2_4_3.cc
index e61e0a3..0e69ca6 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_4_3.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_4_3.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_4_4.cc b/internal/ceres/generated/partitioned_matrix_view_2_4_4.cc
index 2e1170d..ba9bb61 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_4_4.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_4_4.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_4_6.cc b/internal/ceres/generated/partitioned_matrix_view_2_4_6.cc
index 4a5590d..1acdb9b 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_4_6.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_4_6.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_4_8.cc b/internal/ceres/generated/partitioned_matrix_view_2_4_8.cc
index 83015f1..888ff99 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_4_8.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_4_8.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_4_9.cc b/internal/ceres/generated/partitioned_matrix_view_2_4_9.cc
index 25671f9..bd4dde3 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_4_9.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_4_9.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_4_d.cc b/internal/ceres/generated/partitioned_matrix_view_2_4_d.cc
index d259802..6d3516f 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_4_d.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_4_d.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_2_d_d.cc b/internal/ceres/generated/partitioned_matrix_view_2_d_d.cc
index c956759..77d22ed 100644
--- a/internal/ceres/generated/partitioned_matrix_view_2_d_d.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_2_d_d.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_3_3_3.cc b/internal/ceres/generated/partitioned_matrix_view_3_3_3.cc
new file mode 100644
index 0000000..aeb456c
--- /dev/null
+++ b/internal/ceres/generated/partitioned_matrix_view_3_3_3.cc
@@ -0,0 +1,57 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2017 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+//
+// Template specialization of PartitionedMatrixView.
+//
+// ========================================
+// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
+// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
+// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
+// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
+//=========================================
+//
+// This file is generated using generate_template_specializations.py.
+
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
+#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
+
+#include "ceres/partitioned_matrix_view_impl.h"
+
+namespace ceres {
+namespace internal {
+
+template class PartitionedMatrixView<3, 3, 3>;
+
+}  // namespace internal
+}  // namespace ceres
+
+#endif  // CERES_RESTRICT_SCHUR_SPECIALIZATION
diff --git a/internal/ceres/generated/partitioned_matrix_view_4_4_2.cc b/internal/ceres/generated/partitioned_matrix_view_4_4_2.cc
index f08049c..bb240b9 100644
--- a/internal/ceres/generated/partitioned_matrix_view_4_4_2.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_4_4_2.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_4_4_3.cc b/internal/ceres/generated/partitioned_matrix_view_4_4_3.cc
index 9342612..5d47543 100644
--- a/internal/ceres/generated/partitioned_matrix_view_4_4_3.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_4_4_3.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_4_4_4.cc b/internal/ceres/generated/partitioned_matrix_view_4_4_4.cc
index 8b273fa..e14f980 100644
--- a/internal/ceres/generated/partitioned_matrix_view_4_4_4.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_4_4_4.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_4_4_d.cc b/internal/ceres/generated/partitioned_matrix_view_4_4_d.cc
index e8b45e4..9ec5056 100644
--- a/internal/ceres/generated/partitioned_matrix_view_4_4_d.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_4_4_d.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/partitioned_matrix_view_d_d_d.cc b/internal/ceres/generated/partitioned_matrix_view_d_d_d.cc
index 3545b86..1e12479 100644
--- a/internal/ceres/generated/partitioned_matrix_view_d_d_d.cc
+++ b/internal/ceres/generated/partitioned_matrix_view_d_d_d.cc
@@ -39,14 +39,14 @@
 //
 // This file is generated using generate_template_specializations.py.
 
-
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
 
-template class PartitionedMatrixView<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>;
+template class PartitionedMatrixView<Eigen::Dynamic,
+                                     Eigen::Dynamic,
+                                     Eigen::Dynamic>;
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/generated/schur_eliminator_2_2_2.cc b/internal/ceres/generated/schur_eliminator_2_2_2.cc
index 79fcf43..289a809 100644
--- a/internal/ceres/generated/schur_eliminator_2_2_2.cc
+++ b/internal/ceres/generated/schur_eliminator_2_2_2.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_2_3.cc b/internal/ceres/generated/schur_eliminator_2_2_3.cc
index edd7fb6..20311ba 100644
--- a/internal/ceres/generated/schur_eliminator_2_2_3.cc
+++ b/internal/ceres/generated/schur_eliminator_2_2_3.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_2_4.cc b/internal/ceres/generated/schur_eliminator_2_2_4.cc
index 692267d..1f6a8ae 100644
--- a/internal/ceres/generated/schur_eliminator_2_2_4.cc
+++ b/internal/ceres/generated/schur_eliminator_2_2_4.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_2_d.cc b/internal/ceres/generated/schur_eliminator_2_2_d.cc
index 33d9c6d..08b18d3 100644
--- a/internal/ceres/generated/schur_eliminator_2_2_d.cc
+++ b/internal/ceres/generated/schur_eliminator_2_2_d.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_3_3.cc b/internal/ceres/generated/schur_eliminator_2_3_3.cc
index 4a5e2fe..115b4c8 100644
--- a/internal/ceres/generated/schur_eliminator_2_3_3.cc
+++ b/internal/ceres/generated/schur_eliminator_2_3_3.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_3_4.cc b/internal/ceres/generated/schur_eliminator_2_3_4.cc
index 7ee63d0..c703537 100644
--- a/internal/ceres/generated/schur_eliminator_2_3_4.cc
+++ b/internal/ceres/generated/schur_eliminator_2_3_4.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_3_6.cc b/internal/ceres/generated/schur_eliminator_2_3_6.cc
index 108760e..edb9afe 100644
--- a/internal/ceres/generated/schur_eliminator_2_3_6.cc
+++ b/internal/ceres/generated/schur_eliminator_2_3_6.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_3_9.cc b/internal/ceres/generated/schur_eliminator_2_3_9.cc
index 4fea2fa..faa5c19 100644
--- a/internal/ceres/generated/schur_eliminator_2_3_9.cc
+++ b/internal/ceres/generated/schur_eliminator_2_3_9.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_3_d.cc b/internal/ceres/generated/schur_eliminator_2_3_d.cc
index 0d13c99..81b6f97 100644
--- a/internal/ceres/generated/schur_eliminator_2_3_d.cc
+++ b/internal/ceres/generated/schur_eliminator_2_3_d.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_4_3.cc b/internal/ceres/generated/schur_eliminator_2_4_3.cc
index 3827c65..2cb2d15 100644
--- a/internal/ceres/generated/schur_eliminator_2_4_3.cc
+++ b/internal/ceres/generated/schur_eliminator_2_4_3.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_4_4.cc b/internal/ceres/generated/schur_eliminator_2_4_4.cc
index 47bdfab..a78eff3 100644
--- a/internal/ceres/generated/schur_eliminator_2_4_4.cc
+++ b/internal/ceres/generated/schur_eliminator_2_4_4.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_4_6.cc b/internal/ceres/generated/schur_eliminator_2_4_6.cc
index 3777be2..e2534f2 100644
--- a/internal/ceres/generated/schur_eliminator_2_4_6.cc
+++ b/internal/ceres/generated/schur_eliminator_2_4_6.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_4_8.cc b/internal/ceres/generated/schur_eliminator_2_4_8.cc
index 862c76a..296a462 100644
--- a/internal/ceres/generated/schur_eliminator_2_4_8.cc
+++ b/internal/ceres/generated/schur_eliminator_2_4_8.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_4_9.cc b/internal/ceres/generated/schur_eliminator_2_4_9.cc
index 5b5b7cc..0d0b04e 100644
--- a/internal/ceres/generated/schur_eliminator_2_4_9.cc
+++ b/internal/ceres/generated/schur_eliminator_2_4_9.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_4_d.cc b/internal/ceres/generated/schur_eliminator_2_4_d.cc
index ce2d450..7979926 100644
--- a/internal/ceres/generated/schur_eliminator_2_4_d.cc
+++ b/internal/ceres/generated/schur_eliminator_2_4_d.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_2_d_d.cc b/internal/ceres/generated/schur_eliminator_2_d_d.cc
index 9b02bd9..189be04 100644
--- a/internal/ceres/generated/schur_eliminator_2_d_d.cc
+++ b/internal/ceres/generated/schur_eliminator_2_d_d.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_3_3_3.cc b/internal/ceres/generated/schur_eliminator_3_3_3.cc
new file mode 100644
index 0000000..35c14a8
--- /dev/null
+++ b/internal/ceres/generated/schur_eliminator_3_3_3.cc
@@ -0,0 +1,57 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2017 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// 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: sameeragarwal@google.com (Sameer Agarwal)
+//
+// Template specialization of SchurEliminator.
+//
+// ========================================
+// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
+// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
+// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
+// THIS FILE IS AUTOGENERATED. DO NOT EDIT.
+//=========================================
+//
+// This file is generated using generate_template_specializations.py.
+
+// This include must come before any #ifndef check on Ceres compile options.
+#include "ceres/internal/port.h"
+
+#ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
+
+#include "ceres/schur_eliminator_impl.h"
+
+namespace ceres {
+namespace internal {
+
+template class SchurEliminator<3, 3, 3>;
+
+}  // namespace internal
+}  // namespace ceres
+
+#endif  // CERES_RESTRICT_SCHUR_SPECIALIZATION
diff --git a/internal/ceres/generated/schur_eliminator_4_4_2.cc b/internal/ceres/generated/schur_eliminator_4_4_2.cc
index 10f709d..878500a 100644
--- a/internal/ceres/generated/schur_eliminator_4_4_2.cc
+++ b/internal/ceres/generated/schur_eliminator_4_4_2.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_4_4_3.cc b/internal/ceres/generated/schur_eliminator_4_4_3.cc
index bcbcc74..c4b0959 100644
--- a/internal/ceres/generated/schur_eliminator_4_4_3.cc
+++ b/internal/ceres/generated/schur_eliminator_4_4_3.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_4_4_4.cc b/internal/ceres/generated/schur_eliminator_4_4_4.cc
index 44ecc87..20df534 100644
--- a/internal/ceres/generated/schur_eliminator_4_4_4.cc
+++ b/internal/ceres/generated/schur_eliminator_4_4_4.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_4_4_d.cc b/internal/ceres/generated/schur_eliminator_4_4_d.cc
index 69c8563..17368dc 100644
--- a/internal/ceres/generated/schur_eliminator_4_4_d.cc
+++ b/internal/ceres/generated/schur_eliminator_4_4_d.cc
@@ -45,7 +45,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated/schur_eliminator_d_d_d.cc b/internal/ceres/generated/schur_eliminator_d_d_d.cc
index 348708b..ca598fe 100644
--- a/internal/ceres/generated/schur_eliminator_d_d_d.cc
+++ b/internal/ceres/generated/schur_eliminator_d_d_d.cc
@@ -39,9 +39,7 @@
 //
 // This file is generated using generate_template_specializations.py.
 
-
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
diff --git a/internal/ceres/generated_bundle_adjustment_tests/.clang-format b/internal/ceres/generated_bundle_adjustment_tests/.clang-format
new file mode 100644
index 0000000..9d15924
--- /dev/null
+++ b/internal/ceres/generated_bundle_adjustment_tests/.clang-format
@@ -0,0 +1,2 @@
+DisableFormat: true
+SortIncludes: false
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_test.cc
index 642e9f2..c0585e8 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_test.cc
@@ -42,20 +42,18 @@
 
 TEST_F(BundleAdjustmentTest,
        DenseSchur_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = DENSE_SCHUR;
-   options->sparse_linear_algebra_library_type = NO_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = DENSE_SCHUR;
+  options->sparse_linear_algebra_library_type = NO_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_threads_test.cc
index 10b19b7..2ece1b4 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_auto_threads_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        DenseSchur_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = DENSE_SCHUR;
-   options->sparse_linear_algebra_library_type = NO_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = DENSE_SCHUR;
+  options->sparse_linear_algebra_library_type = NO_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_THREADS
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_test.cc
index f852a46..983c09e 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_test.cc
@@ -42,20 +42,18 @@
 
 TEST_F(BundleAdjustmentTest,
        DenseSchur_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = DENSE_SCHUR;
-   options->sparse_linear_algebra_library_type = NO_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = DENSE_SCHUR;
+  options->sparse_linear_algebra_library_type = NO_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_threads_test.cc
index 324998f..5b739f9 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_denseschur_user_threads_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        DenseSchur_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = DENSE_SCHUR;
-   options->sparse_linear_algebra_library_type = NO_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = DENSE_SCHUR;
+  options->sparse_linear_algebra_library_type = NO_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_THREADS
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_test.cc
index 30443af..f2a6661 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_AccelerateSparse_ClusterJacobi_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_threads_test.cc
index f61e1d6..0178c67 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_AccelerateSparse_ClusterJacobi_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_test.cc
index 6de1e4b..6f29df5 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_AccelerateSparse_ClusterJacobi_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_threads_test.cc
index 74cb674..c92b364 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clustjacobi_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_AccelerateSparse_ClusterJacobi_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_test.cc
index 4168466..576a251 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_AccelerateSparse_ClusterTridiagonal_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_threads_test.cc
index 11c962b..363c92a 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_AccelerateSparse_ClusterTridiagonal_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_test.cc
index b8cb11d..7444a77 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_AccelerateSparse_ClusterTridiagonal_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_threads_test.cc
index ff2e8de..f258e6b 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_acceleratesparse_clusttri_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_AccelerateSparse_ClusterTridiagonal_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_auto_test.cc
index 4ee23a5..9f7032b 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_CxSparse_ClusterJacobi_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_auto_threads_test.cc
index 85c5d83..3d807cf 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_CxSparse_ClusterJacobi_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_user_test.cc
index 5b03651..5883d12 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_CxSparse_ClusterJacobi_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_user_threads_test.cc
index e855875..b98933d 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clustjacobi_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_CxSparse_ClusterJacobi_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_auto_test.cc
index acc6e0d..f29e939 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_CxSparse_ClusterTridiagonal_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_auto_threads_test.cc
index 62c9924..b45d65c 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_CxSparse_ClusterTridiagonal_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_user_test.cc
index bd86d9c..35a68e8 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_CxSparse_ClusterTridiagonal_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_user_threads_test.cc
index ea53a6e..ac3dc25 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_cxsparse_clusttri_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_CxSparse_ClusterTridiagonal_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_auto_test.cc
index 78cd02e..92b3021 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_EigenSparse_ClusterJacobi_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_auto_threads_test.cc
index 83693b1..dc72edf 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_EigenSparse_ClusterJacobi_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_user_test.cc
index dcc42cd..576b8be 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_EigenSparse_ClusterJacobi_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_user_threads_test.cc
index 8566dce..786c19a 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clustjacobi_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_EigenSparse_ClusterJacobi_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_auto_test.cc
index aef25fe..cb3c958 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_EigenSparse_ClusterTridiagonal_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_auto_threads_test.cc
index 58389c6..3851bfc 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_EigenSparse_ClusterTridiagonal_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_user_test.cc
index eee6da0..0df51c2 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_EigenSparse_ClusterTridiagonal_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_user_threads_test.cc
index 826239b..33c6bb8 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_eigensparse_clusttri_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_EigenSparse_ClusterTridiagonal_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_test.cc
index e59be90..78d8d44 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_test.cc
@@ -42,20 +42,18 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_Jacobi_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = NO_SPARSE;
-   options->preconditioner_type = JACOBI;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = NO_SPARSE;
+  options->preconditioner_type = JACOBI;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_threads_test.cc
index 7bcdad2..98fa68b 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_auto_threads_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_Jacobi_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = NO_SPARSE;
-   options->preconditioner_type = JACOBI;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = NO_SPARSE;
+  options->preconditioner_type = JACOBI;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_THREADS
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_test.cc
index c58f2fd..07fa0a0 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_test.cc
@@ -42,20 +42,18 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_Jacobi_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = NO_SPARSE;
-   options->preconditioner_type = JACOBI;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = NO_SPARSE;
+  options->preconditioner_type = JACOBI;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_threads_test.cc
index ef73824..3244173 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_jacobi_user_threads_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_Jacobi_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = NO_SPARSE;
-   options->preconditioner_type = JACOBI;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = NO_SPARSE;
+  options->preconditioner_type = JACOBI;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_THREADS
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_test.cc
index 0f775e1..61f2c51 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_test.cc
@@ -42,20 +42,18 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SchurJacobi_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = NO_SPARSE;
-   options->preconditioner_type = SCHUR_JACOBI;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = NO_SPARSE;
+  options->preconditioner_type = SCHUR_JACOBI;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_threads_test.cc
index 9d91c81..3bfb35c 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_auto_threads_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SchurJacobi_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = NO_SPARSE;
-   options->preconditioner_type = SCHUR_JACOBI;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = NO_SPARSE;
+  options->preconditioner_type = SCHUR_JACOBI;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_THREADS
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_test.cc
index 564104c..f84b561 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_test.cc
@@ -42,20 +42,18 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SchurJacobi_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = NO_SPARSE;
-   options->preconditioner_type = SCHUR_JACOBI;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = NO_SPARSE;
+  options->preconditioner_type = SCHUR_JACOBI;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_threads_test.cc
index f37de7a..9206290 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_schurjacobi_user_threads_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SchurJacobi_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = NO_SPARSE;
-   options->preconditioner_type = SCHUR_JACOBI;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = NO_SPARSE;
+  options->preconditioner_type = SCHUR_JACOBI;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_THREADS
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_test.cc
index 71b774e..ec63ae1 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterJacobi_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_threads_test.cc
index 23706a6..de40b81 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterJacobi_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_test.cc
index e2a3bb2..5406840 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterJacobi_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_threads_test.cc
index 05b270c..9e8aeec 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clustjacobi_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterJacobi_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = CLUSTER_JACOBI;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = CLUSTER_JACOBI;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_test.cc
index 04ad42e..fc80339 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterTridiagonal_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_threads_test.cc
index 2164c11..f4962ab 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterTridiagonal_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_test.cc
index a0c213c..7f99834 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterTridiagonal_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_threads_test.cc
index 15eb761..041b77a 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_iterschur_suitesparse_clusttri_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        IterativeSchur_SuiteSparse_ClusterTridiagonal_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = ITERATIVE_SCHUR;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = CLUSTER_TRIDIAGONAL;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = ITERATIVE_SCHUR;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = CLUSTER_TRIDIAGONAL;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_test.cc
index 4683d2b..95d6259 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_AccelerateSparse_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_threads_test.cc
index 1b63415..cf525bc 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_AccelerateSparse_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_test.cc
index bdc7d62..01c86f8 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_AccelerateSparse_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_threads_test.cc
index 36567f1..b562b99 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_acceleratesparse_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_AccelerateSparse_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_test.cc
index b47daef..aa0dc2c 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_CxSparse_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_threads_test.cc
index 22d1002..367c4fb 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_CxSparse_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_test.cc
index e0c5268..523e031 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_CxSparse_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_threads_test.cc
index 2ea905a..e1923ee 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_cxsparse_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_CxSparse_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_test.cc
index ce502d6..e9202e9 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_EigenSparse_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_threads_test.cc
index b91a6d4..769e3c8 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_EigenSparse_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_test.cc
index e17caf6..87763c5 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_EigenSparse_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_threads_test.cc
index b17f480..38e10d9 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_eigensparse_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_EigenSparse_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_test.cc
index e114a51..fd9b6e7 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_SuiteSparse_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_threads_test.cc
index 3340f2f..476087b 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_SuiteSparse_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_test.cc
index 8998e90..be64ae8 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_SuiteSparse_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_threads_test.cc
index b13e26d..d6a2653 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparsecholesky_suitesparse_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseNormalCholesky_SuiteSparse_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_test.cc
index b43a26a..923eca4 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_AccelerateSparse_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_threads_test.cc
index 7e330c4..8b1a613 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_AccelerateSparse_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_test.cc
index b5738b7..b107c68 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_AccelerateSparse_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_threads_test.cc
index b5c6105..a765e8a 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_acceleratesparse_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_AccelerateSparse_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_ACCELERATE_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_test.cc
index 6d9fb7c..5f2d3d9 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_CxSparse_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_threads_test.cc
index 69e8cce..791e8af 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_CxSparse_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_test.cc
index f60b7c1..260d2d7 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_CxSparse_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_threads_test.cc
index cfb9798..bf01577 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_cxsparse_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_CxSparse_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = CX_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = CX_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_CXSPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_test.cc
index a143591..eeac03c 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_EigenSparse_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_threads_test.cc
index 111c2a4..86d4ce4 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_EigenSparse_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_test.cc
index 9ad242e..434b466 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_EigenSparse_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_threads_test.cc
index abd914d..db6e0cf 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_eigensparse_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_EigenSparse_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = EIGEN_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_USE_EIGEN_SPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_test.cc
index 21d0e50..8dd0117 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_SuiteSparse_AutomaticOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_threads_test.cc
index 145eb9d..b497938 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_auto_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_SuiteSparse_AutomaticOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kAutomaticOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kAutomaticOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_test.cc
index f73cc7d..1a38e9e 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_test.cc
@@ -44,22 +44,20 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_SuiteSparse_UserOrdering) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 1;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 1;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
 }  // namespace ceres
 
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_threads_test.cc b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_threads_test.cc
index b0d67d7..05f28af 100644
--- a/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_threads_test.cc
+++ b/internal/ceres/generated_bundle_adjustment_tests/ba_sparseschur_suitesparse_user_threads_test.cc
@@ -45,18 +45,17 @@
 
 TEST_F(BundleAdjustmentTest,
        SparseSchur_SuiteSparse_UserOrdering_Threads) {  // NOLINT
-   BundleAdjustmentProblem bundle_adjustment_problem;
-   Solver::Options* options =
-     bundle_adjustment_problem.mutable_solver_options();
-   options->num_threads = 4;
-   options->linear_solver_type = SPARSE_SCHUR;
-   options->sparse_linear_algebra_library_type = SUITE_SPARSE;
-   options->preconditioner_type = IDENTITY;
-   if (kUserOrdering) {
-     options->linear_solver_ordering.reset();
-   }
-   Problem* problem = bundle_adjustment_problem.mutable_problem();
-   RunSolverForConfigAndExpectResidualsMatch(*options, problem);
+  BundleAdjustmentProblem bundle_adjustment_problem;
+  Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+  options->num_threads = 4;
+  options->linear_solver_type = SPARSE_SCHUR;
+  options->sparse_linear_algebra_library_type = SUITE_SPARSE;
+  options->preconditioner_type = IDENTITY;
+  if (kUserOrdering) {
+    options->linear_solver_ordering.reset();
+  }
+  Problem* problem = bundle_adjustment_problem.mutable_problem();
+  RunSolverForConfigAndExpectResidualsMatch(*options, problem);
 }
 
 }  // namespace internal
@@ -64,4 +63,3 @@
 
 #endif  // CERES_NO_THREADS
 #endif  // CERES_NO_SUITESPARSE
-
diff --git a/internal/ceres/gmock/.clang-format b/internal/ceres/gmock/.clang-format
new file mode 100644
index 0000000..9d15924
--- /dev/null
+++ b/internal/ceres/gmock/.clang-format
@@ -0,0 +1,2 @@
+DisableFormat: true
+SortIncludes: false
diff --git a/internal/ceres/gmock/gmock.h b/internal/ceres/gmock/gmock.h
index cd54177..2180319 100644
--- a/internal/ceres/gmock/gmock.h
+++ b/internal/ceres/gmock/gmock.h
@@ -26,13 +26,14 @@
 // 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: wan@google.com (Zhanyong Wan)
+
 
 // Google Mock - a framework for writing C++ mock classes.
 //
 // This is the main header file a user should include.
 
+// GOOGLETEST_CM0002 DO NOT DELETE
+
 #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_
 #define GMOCK_INCLUDE_GMOCK_GMOCK_H_
 
@@ -83,13 +84,14 @@
 // 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: wan@google.com (Zhanyong Wan)
+
 
 // Google Mock - a framework for writing C++ mock classes.
 //
 // This file implements some commonly used actions.
 
+// GOOGLETEST_CM0002 DO NOT DELETE
+
 #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
 #define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
 
@@ -98,7 +100,11 @@
 #endif
 
 #include <algorithm>
+#include <functional>
+#include <memory>
 #include <string>
+#include <type_traits>
+#include <utility>
 
 // Copyright 2007, Google Inc.
 // All rights reserved.
@@ -128,8 +134,7 @@
 // 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: wan@google.com (Zhanyong Wan)
+
 
 // Google Mock - a framework for writing C++ mock classes.
 //
@@ -137,56 +142,15 @@
 // Mock.  They are subject to change without notice, so please DO NOT
 // USE THEM IN USER CODE.
 
+// GOOGLETEST_CM0002 DO NOT DELETE
+
 #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
 #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
 
 #include <stdio.h>
 #include <ostream>  // NOLINT
 #include <string>
-
-// This file was GENERATED by command:
-//     pump.py gmock-generated-internal-utils.h.pump
-// DO NOT EDIT BY HAND!!!
-
-// Copyright 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: wan@google.com (Zhanyong Wan)
-
-// Google Mock - a framework for writing C++ mock classes.
-//
-// This file contains template meta-programming utility classes needed
-// for implementing Google Mock.
-
-#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
-#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
-
+#include <type_traits>
 // Copyright 2008, Google Inc.
 // All rights reserved.
 //
@@ -215,8 +179,7 @@
 // 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: vadimb@google.com (Vadim Berman)
+
 //
 // Low-level types and utilities for porting Google Mock to various
 // platforms.  All macros ending with _ and symbols defined in an
@@ -225,6 +188,8 @@
 // end with _ are part of Google Mock's public API and can be used by
 // code outside Google Mock.
 
+// GOOGLETEST_CM0002 DO NOT DELETE
+
 #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
 #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
 
@@ -239,6 +204,7 @@
 // portability utilities to Google Test's gtest-port.h instead of
 // here, as Google Mock depends on Google Test.  Only add a utility
 // here if it's truly specific to Google Mock.
+
 #include "gtest/gtest.h"
 // Copyright 2015, Google Inc.
 // All rights reserved.
@@ -269,33 +235,21 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
-// Injection point for custom user configurations.
-// The following macros can be defined:
-//
-//   Flag related macros:
-//     GMOCK_DECLARE_bool_(name)
-//     GMOCK_DECLARE_int32_(name)
-//     GMOCK_DECLARE_string_(name)
-//     GMOCK_DEFINE_bool_(name, default_val, doc)
-//     GMOCK_DEFINE_int32_(name, default_val, doc)
-//     GMOCK_DEFINE_string_(name, default_val, doc)
+// Injection point for custom user configurations. See README for details
 //
 // ** Custom implementation starts here **
 
+// GOOGLETEST_CM0002 DO NOT DELETE
+
 #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
 #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
 
 #endif  // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
 
-// To avoid conditional compilation everywhere, we make it
-// gmock-port.h's responsibility to #include the header implementing
-// tr1/tuple.  gmock-port.h does this via gtest-port.h, which is
-// guaranteed to pull in the tuple header.
-
-// For MS Visual C++, check the compiler version. At least VS 2003 is
+// For MS Visual C++, check the compiler version. At least VS 2015 is
 // required to compile Google Mock.
-#if defined(_MSC_VER) && _MSC_VER < 1310
-# error "At least Visual C++ 2003 (7.1) is required to compile Google Mock."
+#if defined(_MSC_VER) && _MSC_VER < 1900
+# error "At least Visual C++ 2015 (14.0) is required to compile Google Mock."
 #endif
 
 // Macro for referencing flags.  This is public as we want the user to
@@ -305,18 +259,18 @@
 #if !defined(GMOCK_DECLARE_bool_)
 
 // Macros for declaring flags.
-#define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
-#define GMOCK_DECLARE_int32_(name) \
+# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
+# define GMOCK_DECLARE_int32_(name) \
     extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name)
-#define GMOCK_DECLARE_string_(name) \
+# define GMOCK_DECLARE_string_(name) \
     extern GTEST_API_ ::std::string GMOCK_FLAG(name)
 
 // Macros for defining flags.
-#define GMOCK_DEFINE_bool_(name, default_val, doc) \
+# define GMOCK_DEFINE_bool_(name, default_val, doc) \
     GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
-#define GMOCK_DEFINE_int32_(name, default_val, doc) \
+# define GMOCK_DEFINE_int32_(name, default_val, doc) \
     GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
-#define GMOCK_DEFINE_string_(name, default_val, doc) \
+# define GMOCK_DEFINE_string_(name, default_val, doc) \
     GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
 
 #endif  // !defined(GMOCK_DECLARE_bool_)
@@ -325,247 +279,28 @@
 
 namespace testing {
 
-template <typename T>
+template <typename>
 class Matcher;
 
 namespace internal {
 
-// An IgnoredValue object can be implicitly constructed from ANY value.
-// This is used in implementing the IgnoreResult(a) action.
-class IgnoredValue {
- public:
-  // This constructor template allows any value to be implicitly
-  // converted to IgnoredValue.  The object has no data member and
-  // doesn't try to remember anything about the argument.  We
-  // deliberately omit the 'explicit' keyword in order to allow the
-  // conversion to be implicit.
-  template <typename T>
-  IgnoredValue(const T& /* ignored */) {}  // NOLINT(runtime/explicit)
-};
+// Silence MSVC C4100 (unreferenced formal parameter) and
+// C4805('==': unsafe mix of type 'const int' and type 'const bool')
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable:4100)
+# pragma warning(disable:4805)
+#endif
 
-// MatcherTuple<T>::type is a tuple type where each field is a Matcher
-// for the corresponding field in tuple type T.
-template <typename Tuple>
-struct MatcherTuple;
-
-template <>
-struct MatcherTuple< ::testing::tuple<> > {
-  typedef ::testing::tuple< > type;
-};
-
-template <typename A1>
-struct MatcherTuple< ::testing::tuple<A1> > {
-  typedef ::testing::tuple<Matcher<A1> > type;
-};
-
-template <typename A1, typename A2>
-struct MatcherTuple< ::testing::tuple<A1, A2> > {
-  typedef ::testing::tuple<Matcher<A1>, Matcher<A2> > type;
-};
-
-template <typename A1, typename A2, typename A3>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3> > {
-  typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4> > {
-  typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>,
-      Matcher<A4> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4, typename A5>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5> > {
-  typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
-      Matcher<A5> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4, typename A5,
-    typename A6>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6> > {
-  typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
-      Matcher<A5>, Matcher<A6> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4, typename A5,
-    typename A6, typename A7>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > {
-  typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
-      Matcher<A5>, Matcher<A6>, Matcher<A7> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4, typename A5,
-    typename A6, typename A7, typename A8>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
-  typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
-      Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4, typename A5,
-    typename A6, typename A7, typename A8, typename A9>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
-  typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
-      Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4, typename A5,
-    typename A6, typename A7, typename A8, typename A9, typename A10>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
-    A10> > {
-  typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
-      Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9>,
-      Matcher<A10> > type;
-};
-
-// Template struct Function<F>, where F must be a function type, contains
-// the following typedefs:
-//
-//   Result:               the function's return type.
-//   ArgumentN:            the type of the N-th argument, where N starts with 1.
-//   ArgumentTuple:        the tuple type consisting of all parameters of F.
-//   ArgumentMatcherTuple: the tuple type consisting of Matchers for all
-//                         parameters of F.
-//   MakeResultVoid:       the function type obtained by substituting void
-//                         for the return type of F.
-//   MakeResultIgnoredValue:
-//                         the function type obtained by substituting Something
-//                         for the return type of F.
-template <typename F>
-struct Function;
-
-template <typename R>
-struct Function<R()> {
-  typedef R Result;
-  typedef ::testing::tuple<> ArgumentTuple;
-  typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
-  typedef void MakeResultVoid();
-  typedef IgnoredValue MakeResultIgnoredValue();
-};
-
-template <typename R, typename A1>
-struct Function<R(A1)>
-    : Function<R()> {
-  typedef A1 Argument1;
-  typedef ::testing::tuple<A1> ArgumentTuple;
-  typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
-  typedef void MakeResultVoid(A1);
-  typedef IgnoredValue MakeResultIgnoredValue(A1);
-};
-
-template <typename R, typename A1, typename A2>
-struct Function<R(A1, A2)>
-    : Function<R(A1)> {
-  typedef A2 Argument2;
-  typedef ::testing::tuple<A1, A2> ArgumentTuple;
-  typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
-  typedef void MakeResultVoid(A1, A2);
-  typedef IgnoredValue MakeResultIgnoredValue(A1, A2);
-};
-
-template <typename R, typename A1, typename A2, typename A3>
-struct Function<R(A1, A2, A3)>
-    : Function<R(A1, A2)> {
-  typedef A3 Argument3;
-  typedef ::testing::tuple<A1, A2, A3> ArgumentTuple;
-  typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
-  typedef void MakeResultVoid(A1, A2, A3);
-  typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4>
-struct Function<R(A1, A2, A3, A4)>
-    : Function<R(A1, A2, A3)> {
-  typedef A4 Argument4;
-  typedef ::testing::tuple<A1, A2, A3, A4> ArgumentTuple;
-  typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
-  typedef void MakeResultVoid(A1, A2, A3, A4);
-  typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5>
-struct Function<R(A1, A2, A3, A4, A5)>
-    : Function<R(A1, A2, A3, A4)> {
-  typedef A5 Argument5;
-  typedef ::testing::tuple<A1, A2, A3, A4, A5> ArgumentTuple;
-  typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
-  typedef void MakeResultVoid(A1, A2, A3, A4, A5);
-  typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6>
-struct Function<R(A1, A2, A3, A4, A5, A6)>
-    : Function<R(A1, A2, A3, A4, A5)> {
-  typedef A6 Argument6;
-  typedef ::testing::tuple<A1, A2, A3, A4, A5, A6> ArgumentTuple;
-  typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
-  typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6);
-  typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6, typename A7>
-struct Function<R(A1, A2, A3, A4, A5, A6, A7)>
-    : Function<R(A1, A2, A3, A4, A5, A6)> {
-  typedef A7 Argument7;
-  typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> ArgumentTuple;
-  typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
-  typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7);
-  typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6, typename A7, typename A8>
-struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8)>
-    : Function<R(A1, A2, A3, A4, A5, A6, A7)> {
-  typedef A8 Argument8;
-  typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> ArgumentTuple;
-  typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
-  typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8);
-  typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6, typename A7, typename A8, typename A9>
-struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)>
-    : Function<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
-  typedef A9 Argument9;
-  typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> ArgumentTuple;
-  typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
-  typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9);
-  typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
-      A9);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6, typename A7, typename A8, typename A9,
-    typename A10>
-struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
-    : Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
-  typedef A10 Argument10;
-  typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
-      A10> ArgumentTuple;
-  typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
-  typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
-  typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
-      A9, A10);
-};
-
-}  // namespace internal
-
-}  // namespace testing
-
-#endif  // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
-
-namespace testing {
-namespace internal {
+// Joins a vector of strings as if they are fields of a tuple; returns
+// the joined string.
+GTEST_API_ std::string JoinAsTuple(const Strings& fields);
 
 // Converts an identifier name to a space-separated list of lower-case
 // words.  Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
 // treated as one word.  For example, both "FooBar123" and
 // "foo_bar_123" are converted to "foo bar 123".
-GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name);
+GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);
 
 // PointeeOf<Pointer>::type is the type of a value pointed to by a
 // Pointer, which can be either a smart pointer or a raw pointer.  The
@@ -592,25 +327,11 @@
 template <typename Element>
 inline Element* GetRawPointer(Element* p) { return p; }
 
-// This comparator allows linked_ptr to be stored in sets.
-template <typename T>
-struct LinkedPtrLessThan {
-  bool operator()(const ::testing::internal::linked_ptr<T>& lhs,
-                  const ::testing::internal::linked_ptr<T>& rhs) const {
-    return lhs.get() < rhs.get();
-  }
-};
-
-// Symbian compilation can be done with wchar_t being either a native
-// type or a typedef.  Using Google Mock with OpenC without wchar_t
-// should require the definition of _STLP_NO_WCHAR_T.
-//
 // MSVC treats wchar_t as a native type usually, but treats it as the
 // same as unsigned short when the compiler option /Zc:wchar_t- is
 // specified.  It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
 // is a native type.
-#if (GTEST_OS_SYMBIAN && defined(_STLP_NO_WCHAR_T)) || \
-    (defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED))
+#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)
 // wchar_t is a typedef.
 #else
 # define GMOCK_WCHAR_T_IS_NATIVE_ 1
@@ -626,9 +347,11 @@
 // To gcc,
 //   wchar_t == signed wchar_t != unsigned wchar_t == unsigned int
 #ifdef __GNUC__
+#if !defined(__WCHAR_UNSIGNED__)
 // signed/unsigned wchar_t are valid types.
 # define GMOCK_HAS_SIGNED_WCHAR_T_ 1
 #endif
+#endif
 
 // In what follows, we use the term "kind" to indicate whether a type
 // is bool, an integer type (excluding bool), a floating-point type,
@@ -779,7 +502,7 @@
 
   // Reports a failure that occurred at the given source file location.
   virtual void ReportFailure(FailureType type, const char* file, int line,
-                             const string& message) = 0;
+                             const std::string& message) = 0;
 };
 
 // Returns the failure reporter used by Google Mock.
@@ -791,7 +514,7 @@
 // inline this function to prevent it from showing up in the stack
 // trace.
 inline void Assert(bool condition, const char* file, int line,
-                   const string& msg) {
+                   const std::string& msg) {
   if (!condition) {
     GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal,
                                         file, line, msg);
@@ -804,7 +527,7 @@
 // Verifies that condition is true; generates a non-fatal failure if
 // condition is false.
 inline void Expect(bool condition, const char* file, int line,
-                   const string& msg) {
+                   const std::string& msg) {
   if (!condition) {
     GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,
                                         file, line, msg);
@@ -840,11 +563,23 @@
 // stack_frames_to_skip is treated as 0, since we don't know which
 // function calls will be inlined by the compiler and need to be
 // conservative.
-GTEST_API_ void Log(LogSeverity severity,
-                    const string& message,
+GTEST_API_ void Log(LogSeverity severity, const std::string& message,
                     int stack_frames_to_skip);
 
-// TODO(wan@google.com): group all type utilities together.
+// A marker class that is used to resolve parameterless expectations to the
+// correct overload. This must not be instantiable, to prevent client code from
+// accidentally resolving to the overload; for example:
+//
+//    ON_CALL(mock, Method({}, nullptr))...
+//
+class WithoutMatchers {
+ private:
+  WithoutMatchers() {}
+  friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
+};
+
+// Internal use only: access the singleton instance of WithoutMatchers.
+GTEST_API_ WithoutMatchers GetWithoutMatchers();
 
 // Type traits.
 
@@ -945,39 +680,17 @@
   static const_reference ConstReference(const Element (&array)[N]) {
     // Ensures that Element is not a const type.
     testing::StaticAssertTypeEq<Element, RawElement>();
-#if GTEST_OS_SYMBIAN
-    // The Nokia Symbian compiler confuses itself in template instantiation
-    // for this call without the cast to Element*:
-    // function call '[testing::internal::NativeArray<char *>].NativeArray(
-    //     {lval} const char *[4], long, testing::internal::RelationToSource)'
-    //     does not match
-    // 'testing::internal::NativeArray<char *>::NativeArray(
-    //     char *const *, unsigned int, testing::internal::RelationToSource)'
-    // (instantiating: 'testing::internal::ContainsMatcherImpl
-    //     <const char * (&)[4]>::Matches(const char * (&)[4]) const')
-    // (instantiating: 'testing::internal::StlContainerView<char *[4]>::
-    //     ConstReference(const char * (&)[4])')
-    // (and though the N parameter type is mismatched in the above explicit
-    // conversion of it doesn't help - only the conversion of the array).
-    return type(const_cast<Element*>(&array[0]), N,
-                RelationToSourceReference());
-#else
     return type(array, N, RelationToSourceReference());
-#endif  // GTEST_OS_SYMBIAN
   }
   static type Copy(const Element (&array)[N]) {
-#if GTEST_OS_SYMBIAN
-    return type(const_cast<Element*>(&array[0]), N, RelationToSourceCopy());
-#else
     return type(array, N, RelationToSourceCopy());
-#endif  // GTEST_OS_SYMBIAN
   }
 };
 
 // This specialization is used when RawContainer is a native array
 // represented as a (pointer, size) tuple.
 template <typename ElementPointer, typename Size>
-class StlContainerView< ::testing::tuple<ElementPointer, Size> > {
+class StlContainerView< ::std::tuple<ElementPointer, Size> > {
  public:
   typedef GTEST_REMOVE_CONST_(
       typename internal::PointeeOf<ElementPointer>::type) RawElement;
@@ -985,11 +698,12 @@
   typedef const type const_reference;
 
   static const_reference ConstReference(
-      const ::testing::tuple<ElementPointer, Size>& array) {
-    return type(get<0>(array), get<1>(array), RelationToSourceReference());
+      const ::std::tuple<ElementPointer, Size>& array) {
+    return type(std::get<0>(array), std::get<1>(array),
+                RelationToSourceReference());
   }
-  static type Copy(const ::testing::tuple<ElementPointer, Size>& array) {
-    return type(get<0>(array), get<1>(array), RelationToSourceCopy());
+  static type Copy(const ::std::tuple<ElementPointer, Size>& array) {
+    return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy());
   }
 };
 
@@ -1016,14 +730,80 @@
 template <bool kValue>
 struct BooleanConstant {};
 
+// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to
+// reduce code size.
+GTEST_API_ void IllegalDoDefault(const char* file, int line);
+
+// Helper types for Apply() below.
+template <size_t... Is> struct int_pack { typedef int_pack type; };
+
+template <class Pack, size_t I> struct append;
+template <size_t... Is, size_t I>
+struct append<int_pack<Is...>, I> : int_pack<Is..., I> {};
+
+template <size_t C>
+struct make_int_pack : append<typename make_int_pack<C - 1>::type, C - 1> {};
+template <> struct make_int_pack<0> : int_pack<> {};
+
+template <typename F, typename Tuple, size_t... Idx>
+auto ApplyImpl(F&& f, Tuple&& args, int_pack<Idx...>) -> decltype(
+    std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...)) {
+  return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
+}
+
+// Apply the function to a tuple of arguments.
+template <typename F, typename Tuple>
+auto Apply(F&& f, Tuple&& args)
+    -> decltype(ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
+                          make_int_pack<std::tuple_size<Tuple>::value>())) {
+  return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
+                   make_int_pack<std::tuple_size<Tuple>::value>());
+}
+
+// Template struct Function<F>, where F must be a function type, contains
+// the following typedefs:
+//
+//   Result:               the function's return type.
+//   Arg<N>:               the type of the N-th argument, where N starts with 0.
+//   ArgumentTuple:        the tuple type consisting of all parameters of F.
+//   ArgumentMatcherTuple: the tuple type consisting of Matchers for all
+//                         parameters of F.
+//   MakeResultVoid:       the function type obtained by substituting void
+//                         for the return type of F.
+//   MakeResultIgnoredValue:
+//                         the function type obtained by substituting Something
+//                         for the return type of F.
+template <typename T>
+struct Function;
+
+template <typename R, typename... Args>
+struct Function<R(Args...)> {
+  using Result = R;
+  static constexpr size_t ArgumentCount = sizeof...(Args);
+  template <size_t I>
+  using Arg = ElemFromList<I, typename MakeIndexSequence<sizeof...(Args)>::type,
+                           Args...>;
+  using ArgumentTuple = std::tuple<Args...>;
+  using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
+  using MakeResultVoid = void(Args...);
+  using MakeResultIgnoredValue = IgnoredValue(Args...);
+};
+
+template <typename R, typename... Args>
+constexpr size_t Function<R(Args...)>::ArgumentCount;
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
 }  // namespace internal
 }  // namespace testing
 
 #endif  // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
 
-
-#if GTEST_HAS_STD_TYPE_TRAITS_  // Defined by gtest-port.h via gmock-port.h.
-#include <type_traits>
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable:4100)
 #endif
 
 namespace testing {
@@ -1039,9 +819,6 @@
 
 namespace internal {
 
-template <typename F1, typename F2>
-class ActionAdaptor;
-
 // BuiltInDefaultValueGetter<T, true>::Get() returns a
 // default-constructed T value.  BuiltInDefaultValueGetter<T,
 // false>::Get() crashes with an error.
@@ -1072,7 +849,6 @@
 template <typename T>
 class BuiltInDefaultValue {
  public:
-#if GTEST_HAS_STD_TYPE_TRAITS_
   // This function returns true iff type T has a built-in default value.
   static bool Exists() {
     return ::std::is_default_constructible<T>::value;
@@ -1082,18 +858,6 @@
     return BuiltInDefaultValueGetter<
         T, ::std::is_default_constructible<T>::value>::Get();
   }
-
-#else  // GTEST_HAS_STD_TYPE_TRAITS_
-  // This function returns true iff type T has a built-in default value.
-  static bool Exists() {
-    return false;
-  }
-
-  static T Get() {
-    return BuiltInDefaultValueGetter<T, false>::Get();
-  }
-
-#endif  // GTEST_HAS_STD_TYPE_TRAITS_
 };
 
 // This partial specialization says that we use the same built-in
@@ -1111,7 +875,7 @@
 class BuiltInDefaultValue<T*> {
  public:
   static bool Exists() { return true; }
-  static T* Get() { return NULL; }
+  static T* Get() { return nullptr; }
 };
 
 // The following specializations define the default values for
@@ -1194,11 +958,11 @@
   // Unsets the default value for type T.
   static void Clear() {
     delete producer_;
-    producer_ = NULL;
+    producer_ = nullptr;
   }
 
   // Returns true iff the user has set the default value for type T.
-  static bool IsSet() { return producer_ != NULL; }
+  static bool IsSet() { return producer_ != nullptr; }
 
   // Returns true if T has a default return value set by the user or there
   // exists a built-in default value.
@@ -1210,8 +974,8 @@
   // otherwise returns the built-in default value. Requires that Exists()
   // is true, which ensures that the return value is well-defined.
   static T Get() {
-    return producer_ == NULL ?
-        internal::BuiltInDefaultValue<T>::Get() : producer_->Produce();
+    return producer_ == nullptr ? internal::BuiltInDefaultValue<T>::Get()
+                                : producer_->Produce();
   }
 
  private:
@@ -1224,7 +988,7 @@
   class FixedValueProducer : public ValueProducer {
    public:
     explicit FixedValueProducer(T value) : value_(value) {}
-    virtual T Produce() { return value_; }
+    T Produce() override { return value_; }
 
    private:
     const T value_;
@@ -1235,7 +999,7 @@
    public:
     explicit FactoryValueProducer(FactoryFunction factory)
         : factory_(factory) {}
-    virtual T Produce() { return factory_(); }
+    T Produce() override { return factory_(); }
 
    private:
     const FactoryFunction factory_;
@@ -1256,12 +1020,10 @@
   }
 
   // Unsets the default value for type T&.
-  static void Clear() {
-    address_ = NULL;
-  }
+  static void Clear() { address_ = nullptr; }
 
   // Returns true iff the user has set the default value for type T&.
-  static bool IsSet() { return address_ != NULL; }
+  static bool IsSet() { return address_ != nullptr; }
 
   // Returns true if T has a default return value set by the user or there
   // exists a built-in default value.
@@ -1273,8 +1035,8 @@
   // otherwise returns the built-in default value if there is one;
   // otherwise aborts the process.
   static T& Get() {
-    return address_ == NULL ?
-        internal::BuiltInDefaultValue<T&>::Get() : *address_;
+    return address_ == nullptr ? internal::BuiltInDefaultValue<T&>::Get()
+                               : *address_;
   }
 
  private:
@@ -1292,11 +1054,11 @@
 
 // Points to the user-set default value for type T.
 template <typename T>
-typename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = NULL;
+typename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = nullptr;
 
 // Points to the user-set default value for type T&.
 template <typename T>
-T* DefaultValue<T&>::address_ = NULL;
+T* DefaultValue<T&>::address_ = nullptr;
 
 // Implement this interface to define an action for function type F.
 template <typename F>
@@ -1321,38 +1083,53 @@
 // An Action<F> is a copyable and IMMUTABLE (except by assignment)
 // object that represents an action to be taken when a mock function
 // of type F is called.  The implementation of Action<T> is just a
-// linked_ptr to const ActionInterface<T>, so copying is fairly cheap.
-// Don't inherit from Action!
-//
+// std::shared_ptr to const ActionInterface<T>. Don't inherit from Action!
 // You can view an object implementing ActionInterface<F> as a
 // concrete action (including its current state), and an Action<F>
 // object as a handle to it.
 template <typename F>
 class Action {
+  // Adapter class to allow constructing Action from a legacy ActionInterface.
+  // New code should create Actions from functors instead.
+  struct ActionAdapter {
+    // Adapter must be copyable to satisfy std::function requirements.
+    ::std::shared_ptr<ActionInterface<F>> impl_;
+
+    template <typename... Args>
+    typename internal::Function<F>::Result operator()(Args&&... args) {
+      return impl_->Perform(
+          ::std::forward_as_tuple(::std::forward<Args>(args)...));
+    }
+  };
+
  public:
   typedef typename internal::Function<F>::Result Result;
   typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
 
   // Constructs a null Action.  Needed for storing Action objects in
   // STL containers.
-  Action() : impl_(NULL) {}
+  Action() {}
 
-  // Constructs an Action from its implementation.  A NULL impl is
-  // used to represent the "do-default" action.
-  explicit Action(ActionInterface<F>* impl) : impl_(impl) {}
+  // Construct an Action from a specified callable.
+  // This cannot take std::function directly, because then Action would not be
+  // directly constructible from lambda (it would require two conversions).
+  template <typename G,
+            typename = typename ::std::enable_if<
+                ::std::is_constructible<::std::function<F>, G>::value>::type>
+  Action(G&& fun) : fun_(::std::forward<G>(fun)) {}  // NOLINT
 
-  // Copy constructor.
-  Action(const Action& action) : impl_(action.impl_) {}
+  // Constructs an Action from its implementation.
+  explicit Action(ActionInterface<F>* impl)
+      : fun_(ActionAdapter{::std::shared_ptr<ActionInterface<F>>(impl)}) {}
 
   // This constructor allows us to turn an Action<Func> object into an
   // Action<F>, as long as F's arguments can be implicitly converted
-  // to Func's and Func's return type can be implicitly converted to
-  // F's.
+  // to Func's and Func's return type can be implicitly converted to F's.
   template <typename Func>
-  explicit Action(const Action<Func>& action);
+  explicit Action(const Action<Func>& action) : fun_(action.fun_) {}
 
   // Returns true iff this is the DoDefault() action.
-  bool IsDoDefault() const { return impl_.get() == NULL; }
+  bool IsDoDefault() const { return fun_ == nullptr; }
 
   // Performs the action.  Note that this method is const even though
   // the corresponding method in ActionInterface is not.  The reason
@@ -1360,22 +1137,19 @@
   // another concrete action, not that the concrete action it binds to
   // cannot change state.  (Think of the difference between a const
   // pointer and a pointer to const.)
-  Result Perform(const ArgumentTuple& args) const {
-    internal::Assert(
-        !IsDoDefault(), __FILE__, __LINE__,
-        "You are using DoDefault() inside a composite action like "
-        "DoAll() or WithArgs().  This is not supported for technical "
-        "reasons.  Please instead spell out the default action, or "
-        "assign the default action to an Action variable and use "
-        "the variable in various places.");
-    return impl_->Perform(args);
+  Result Perform(ArgumentTuple args) const {
+    if (IsDoDefault()) {
+      internal::IllegalDoDefault(__FILE__, __LINE__);
+    }
+    return internal::Apply(fun_, ::std::move(args));
   }
 
  private:
-  template <typename F1, typename F2>
-  friend class internal::ActionAdaptor;
+  template <typename G>
+  friend class Action;
 
-  internal::linked_ptr<ActionInterface<F> > impl_;
+  // fun_ is an empty function iff this is the DoDefault() action.
+  ::std::function<F> fun_;
 };
 
 // The PolymorphicAction class template makes it easy to implement a
@@ -1390,7 +1164,7 @@
 //     template <typename Result, typename ArgumentTuple>
 //     Result Perform(const ArgumentTuple& args) const {
 //       // Processes the arguments and returns a result, using
-//       // tr1::get<N>(args) to get the N-th (0-based) argument in the tuple.
+//       // std::get<N>(args) to get the N-th (0-based) argument in the tuple.
 //     }
 //     ...
 //   };
@@ -1418,7 +1192,7 @@
 
     explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
 
-    virtual Result Perform(const ArgumentTuple& args) {
+    Result Perform(const ArgumentTuple& args) override {
       return impl_.template Perform<Result>(args);
     }
 
@@ -1454,31 +1228,11 @@
 
 namespace internal {
 
-// Allows an Action<F2> object to pose as an Action<F1>, as long as F2
-// and F1 are compatible.
-template <typename F1, typename F2>
-class ActionAdaptor : public ActionInterface<F1> {
- public:
-  typedef typename internal::Function<F1>::Result Result;
-  typedef typename internal::Function<F1>::ArgumentTuple ArgumentTuple;
-
-  explicit ActionAdaptor(const Action<F2>& from) : impl_(from.impl_) {}
-
-  virtual Result Perform(const ArgumentTuple& args) {
-    return impl_->Perform(args);
-  }
-
- private:
-  const internal::linked_ptr<ActionInterface<F2> > impl_;
-
-  GTEST_DISALLOW_ASSIGN_(ActionAdaptor);
-};
-
 // Helper struct to specialize ReturnAction to execute a move instead of a copy
 // on return. Useful for move-only types, but could be used on any type.
 template <typename T>
 struct ByMoveWrapper {
-  explicit ByMoveWrapper(T value) : payload(internal::move(value)) {}
+  explicit ByMoveWrapper(T value) : payload(std::move(value)) {}
   T payload;
 };
 
@@ -1506,18 +1260,21 @@
 // statement, and conversion of the result of Return to Action<T(U)> is a
 // good place for that.
 //
+// The real life example of the above scenario happens when an invocation
+// of gtl::Container() is passed into Return.
+//
 template <typename R>
 class ReturnAction {
  public:
   // Constructs a ReturnAction object from the value to be returned.
   // 'value' is passed by value instead of by const reference in order
   // to allow Return("string literal") to compile.
-  explicit ReturnAction(R value) : value_(new R(internal::move(value))) {}
+  explicit ReturnAction(R value) : value_(new R(std::move(value))) {}
 
   // This template type conversion operator allows Return(x) to be
   // used in ANY function that returns x's type.
   template <typename F>
-  operator Action<F>() const {
+  operator Action<F>() const {  // NOLINT
     // Assert statement belongs here because this is the best place to verify
     // conditions on F. It produces the clearest error messages
     // in most compilers.
@@ -1530,6 +1287,8 @@
     GTEST_COMPILE_ASSERT_(
         !is_reference<Result>::value,
         use_ReturnRef_instead_of_Return_to_return_a_reference);
+    static_assert(!std::is_void<Result>::value,
+                  "Can't use Return() on an action expected to return `void`.");
     return Action<F>(new Impl<R, F>(value_));
   }
 
@@ -1548,11 +1307,11 @@
     // Result to call.  ImplicitCast_ forces the compiler to convert R to
     // Result without considering explicit constructors, thus resolving the
     // ambiguity. value_ is then initialized using its copy constructor.
-    explicit Impl(const linked_ptr<R>& value)
+    explicit Impl(const std::shared_ptr<R>& value)
         : value_before_cast_(*value),
           value_(ImplicitCast_<Result>(value_before_cast_)) {}
 
-    virtual Result Perform(const ArgumentTuple&) { return value_; }
+    Result Perform(const ArgumentTuple&) override { return value_; }
 
    private:
     GTEST_COMPILE_ASSERT_(!is_reference<Result>::value,
@@ -1573,24 +1332,24 @@
     typedef typename Function<F>::Result Result;
     typedef typename Function<F>::ArgumentTuple ArgumentTuple;
 
-    explicit Impl(const linked_ptr<R>& wrapper)
+    explicit Impl(const std::shared_ptr<R>& wrapper)
         : performed_(false), wrapper_(wrapper) {}
 
-    virtual Result Perform(const ArgumentTuple&) {
+    Result Perform(const ArgumentTuple&) override {
       GTEST_CHECK_(!performed_)
           << "A ByMove() action should only be performed once.";
       performed_ = true;
-      return internal::move(wrapper_->payload);
+      return std::move(wrapper_->payload);
     }
 
    private:
     bool performed_;
-    const linked_ptr<R> wrapper_;
+    const std::shared_ptr<R> wrapper_;
 
     GTEST_DISALLOW_ASSIGN_(Impl);
   };
 
-  const linked_ptr<R> value_;
+  const std::shared_ptr<R> value_;
 
   GTEST_DISALLOW_ASSIGN_(ReturnAction);
 };
@@ -1603,13 +1362,7 @@
   // pointer type on compile time.
   template <typename Result, typename ArgumentTuple>
   static Result Perform(const ArgumentTuple&) {
-#if GTEST_LANG_CXX11
     return nullptr;
-#else
-    GTEST_COMPILE_ASSERT_(internal::is_pointer<Result>::value,
-                          ReturnNull_can_be_used_to_return_a_pointer_only);
-    return NULL;
-#endif  // GTEST_LANG_CXX11
   }
 };
 
@@ -1655,9 +1408,7 @@
 
     explicit Impl(T& ref) : ref_(ref) {}  // NOLINT
 
-    virtual Result Perform(const ArgumentTuple&) {
-      return ref_;
-    }
+    Result Perform(const ArgumentTuple&) override { return ref_; }
 
    private:
     T& ref_;
@@ -1704,9 +1455,7 @@
 
     explicit Impl(const T& value) : value_(value) {}  // NOLINT
 
-    virtual Result Perform(const ArgumentTuple&) {
-      return value_;
-    }
+    Result Perform(const ArgumentTuple&) override { return value_; }
 
    private:
     T value_;
@@ -1725,7 +1474,7 @@
   // This template type conversion operator allows DoDefault() to be
   // used in any function.
   template <typename F>
-  operator Action<F>() const { return Action<F>(NULL); }
+  operator Action<F>() const { return Action<F>(); }  // NOLINT
 };
 
 // Implements the Assign action to set a given pointer referent to a
@@ -1786,7 +1535,7 @@
   template <typename Result, typename ArgumentTuple>
   void Perform(const ArgumentTuple& args) const {
     CompileAssertTypesEqual<void, Result>();
-    *::testing::get<N>(args) = value_;
+    *::std::get<N>(args) = value_;
   }
 
  private:
@@ -1809,56 +1558,56 @@
   template <typename Result, typename ArgumentTuple>
   void Perform(const ArgumentTuple& args) const {
     CompileAssertTypesEqual<void, Result>();
-    ::testing::get<N>(args)->CopyFrom(*proto_);
+    ::std::get<N>(args)->CopyFrom(*proto_);
   }
 
  private:
-  const internal::linked_ptr<Proto> proto_;
+  const std::shared_ptr<Proto> proto_;
 
   GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction);
 };
 
+// Implements the Invoke(object_ptr, &Class::Method) action.
+template <class Class, typename MethodPtr>
+struct InvokeMethodAction {
+  Class* const obj_ptr;
+  const MethodPtr method_ptr;
+
+  template <typename... Args>
+  auto operator()(Args&&... args) const
+      -> decltype((obj_ptr->*method_ptr)(std::forward<Args>(args)...)) {
+    return (obj_ptr->*method_ptr)(std::forward<Args>(args)...);
+  }
+};
+
 // Implements the InvokeWithoutArgs(f) action.  The template argument
 // FunctionImpl is the implementation type of f, which can be either a
 // function pointer or a functor.  InvokeWithoutArgs(f) can be used as an
-// Action<F> as long as f's type is compatible with F (i.e. f can be
-// assigned to a tr1::function<F>).
+// Action<F> as long as f's type is compatible with F.
 template <typename FunctionImpl>
-class InvokeWithoutArgsAction {
- public:
-  // The c'tor makes a copy of function_impl (either a function
-  // pointer or a functor).
-  explicit InvokeWithoutArgsAction(FunctionImpl function_impl)
-      : function_impl_(function_impl) {}
+struct InvokeWithoutArgsAction {
+  FunctionImpl function_impl;
 
   // Allows InvokeWithoutArgs(f) to be used as any action whose type is
   // compatible with f.
-  template <typename Result, typename ArgumentTuple>
-  Result Perform(const ArgumentTuple&) { return function_impl_(); }
-
- private:
-  FunctionImpl function_impl_;
-
-  GTEST_DISALLOW_ASSIGN_(InvokeWithoutArgsAction);
+  template <typename... Args>
+  auto operator()(const Args&...) -> decltype(function_impl()) {
+    return function_impl();
+  }
 };
 
 // Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
 template <class Class, typename MethodPtr>
-class InvokeMethodWithoutArgsAction {
- public:
-  InvokeMethodWithoutArgsAction(Class* obj_ptr, MethodPtr method_ptr)
-      : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
+struct InvokeMethodWithoutArgsAction {
+  Class* const obj_ptr;
+  const MethodPtr method_ptr;
 
-  template <typename Result, typename ArgumentTuple>
-  Result Perform(const ArgumentTuple&) const {
-    return (obj_ptr_->*method_ptr_)();
+  using ReturnType = typename std::result_of<MethodPtr(Class*)>::type;
+
+  template <typename... Args>
+  ReturnType operator()(const Args&...) const {
+    return (obj_ptr->*method_ptr)();
   }
-
- private:
-  Class* const obj_ptr_;
-  const MethodPtr method_ptr_;
-
-  GTEST_DISALLOW_ASSIGN_(InvokeMethodWithoutArgsAction);
 };
 
 // Implements the IgnoreResult(action) action.
@@ -1894,7 +1643,7 @@
 
     explicit Impl(const A& action) : action_(action) {}
 
-    virtual void Perform(const ArgumentTuple& args) {
+    void Perform(const ArgumentTuple& args) override {
       // Performs the action and ignores its result.
       action_.Perform(args);
     }
@@ -1915,76 +1664,51 @@
   GTEST_DISALLOW_ASSIGN_(IgnoreResultAction);
 };
 
-// A ReferenceWrapper<T> object represents a reference to type T,
-// which can be either const or not.  It can be explicitly converted
-// from, and implicitly converted to, a T&.  Unlike a reference,
-// ReferenceWrapper<T> can be copied and can survive template type
-// inference.  This is used to support by-reference arguments in the
-// InvokeArgument<N>(...) action.  The idea was from "reference
-// wrappers" in tr1, which we don't have in our source tree yet.
-template <typename T>
-class ReferenceWrapper {
- public:
-  // Constructs a ReferenceWrapper<T> object from a T&.
-  explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {}  // NOLINT
+template <typename InnerAction, size_t... I>
+struct WithArgsAction {
+  InnerAction action;
 
-  // Allows a ReferenceWrapper<T> object to be implicitly converted to
-  // a T&.
-  operator T&() const { return *pointer_; }
- private:
-  T* pointer_;
+  // The inner action could be anything convertible to Action<X>.
+  // We use the conversion operator to detect the signature of the inner Action.
+  template <typename R, typename... Args>
+  operator Action<R(Args...)>() const {  // NOLINT
+    Action<R(typename std::tuple_element<I, std::tuple<Args...>>::type...)>
+        converted(action);
+
+    return [converted](Args... args) -> R {
+      return converted.Perform(std::forward_as_tuple(
+        std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...));
+    };
+  }
 };
 
-// Allows the expression ByRef(x) to be printed as a reference to x.
-template <typename T>
-void PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) {
-  T& value = ref;
-  UniversalPrinter<T&>::Print(value, os);
-}
-
-// Does two actions sequentially.  Used for implementing the DoAll(a1,
-// a2, ...) action.
-template <typename Action1, typename Action2>
-class DoBothAction {
- public:
-  DoBothAction(Action1 action1, Action2 action2)
-      : action1_(action1), action2_(action2) {}
-
-  // This template type conversion operator allows DoAll(a1, ..., a_n)
-  // to be used in ANY function of compatible type.
-  template <typename F>
-  operator Action<F>() const {
-    return Action<F>(new Impl<F>(action1_, action2_));
+template <typename... Actions>
+struct DoAllAction {
+ private:
+  template <typename... Args, size_t... I>
+  std::vector<Action<void(Args...)>> Convert(IndexSequence<I...>) const {
+    return {std::get<I>(actions)...};
   }
 
- private:
-  // Implements the DoAll(...) action for a particular function type F.
-  template <typename F>
-  class Impl : public ActionInterface<F> {
-   public:
-    typedef typename Function<F>::Result Result;
-    typedef typename Function<F>::ArgumentTuple ArgumentTuple;
-    typedef typename Function<F>::MakeResultVoid VoidResult;
+ public:
+  std::tuple<Actions...> actions;
 
-    Impl(const Action<VoidResult>& action1, const Action<F>& action2)
-        : action1_(action1), action2_(action2) {}
-
-    virtual Result Perform(const ArgumentTuple& args) {
-      action1_.Perform(args);
-      return action2_.Perform(args);
-    }
-
-   private:
-    const Action<VoidResult> action1_;
-    const Action<F> action2_;
-
-    GTEST_DISALLOW_ASSIGN_(Impl);
-  };
-
-  Action1 action1_;
-  Action2 action2_;
-
-  GTEST_DISALLOW_ASSIGN_(DoBothAction);
+  template <typename R, typename... Args>
+  operator Action<R(Args...)>() const {  // NOLINT
+    struct Op {
+      std::vector<Action<void(Args...)>> converted;
+      Action<R(Args...)> last;
+      R operator()(Args... args) const {
+        auto tuple_args = std::forward_as_tuple(std::forward<Args>(args)...);
+        for (auto& a : converted) {
+          a.Perform(tuple_args);
+        }
+        return last.Perform(tuple_args);
+      }
+    };
+    return Op{Convert<Args...>(MakeIndexSequence<sizeof...(Actions) - 1>()),
+              std::get<sizeof...(Actions) - 1>(actions)};
+  }
 };
 
 }  // namespace internal
@@ -2005,9 +1729,9 @@
 //     return sqrt(x*x + y*y);
 //   }
 //   ...
-//   EXEPCT_CALL(mock, Foo("abc", _, _))
+//   EXPECT_CALL(mock, Foo("abc", _, _))
 //       .WillOnce(Invoke(DistanceToOriginWithLabel));
-//   EXEPCT_CALL(mock, Bar(5, _, _))
+//   EXPECT_CALL(mock, Bar(5, _, _))
 //       .WillOnce(Invoke(DistanceToOriginWithIndex));
 //
 // you could write
@@ -2017,25 +1741,55 @@
 //     return sqrt(x*x + y*y);
 //   }
 //   ...
-//   EXEPCT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin));
-//   EXEPCT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
+//   EXPECT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin));
+//   EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
 typedef internal::IgnoredValue Unused;
 
-// This constructor allows us to turn an Action<From> object into an
-// Action<To>, as long as To's arguments can be implicitly converted
-// to From's and From's return type cann be implicitly converted to
-// To's.
-template <typename To>
-template <typename From>
-Action<To>::Action(const Action<From>& from)
-    : impl_(new internal::ActionAdaptor<To, From>(from)) {}
+// Creates an action that does actions a1, a2, ..., sequentially in
+// each invocation.
+template <typename... Action>
+internal::DoAllAction<typename std::decay<Action>::type...> DoAll(
+    Action&&... action) {
+  return {std::forward_as_tuple(std::forward<Action>(action)...)};
+}
+
+// WithArg<k>(an_action) creates an action that passes the k-th
+// (0-based) argument of the mock function to an_action and performs
+// it.  It adapts an action accepting one argument to one that accepts
+// multiple arguments.  For convenience, we also provide
+// WithArgs<k>(an_action) (defined below) as a synonym.
+template <size_t k, typename InnerAction>
+internal::WithArgsAction<typename std::decay<InnerAction>::type, k>
+WithArg(InnerAction&& action) {
+  return {std::forward<InnerAction>(action)};
+}
+
+// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
+// the selected arguments of the mock function to an_action and
+// performs it.  It serves as an adaptor between actions with
+// different argument lists.
+template <size_t k, size_t... ks, typename InnerAction>
+internal::WithArgsAction<typename std::decay<InnerAction>::type, k, ks...>
+WithArgs(InnerAction&& action) {
+  return {std::forward<InnerAction>(action)};
+}
+
+// WithoutArgs(inner_action) can be used in a mock function with a
+// non-empty argument list to perform inner_action, which takes no
+// argument.  In other words, it adapts an action accepting no
+// argument to one that accepts (and ignores) arguments.
+template <typename InnerAction>
+internal::WithArgsAction<typename std::decay<InnerAction>::type>
+WithoutArgs(InnerAction&& action) {
+  return {std::forward<InnerAction>(action)};
+}
 
 // Creates an action that returns 'value'.  'value' is passed by value
 // instead of const reference - otherwise Return("string literal")
 // will trigger a compiler error about using array as initializer.
 template <typename R>
 internal::ReturnAction<R> Return(R value) {
-  return internal::ReturnAction<R>(internal::move(value));
+  return internal::ReturnAction<R>(std::move(value));
 }
 
 // Creates an action that returns NULL.
@@ -2068,7 +1822,7 @@
 // invariant.
 template <typename R>
 internal::ByMoveWrapper<R> ByMove(R x) {
-  return internal::ByMoveWrapper<R>(internal::move(x));
+  return internal::ByMoveWrapper<R>(std::move(x));
 }
 
 // Creates an action that does the default action for the give mock function.
@@ -2087,10 +1841,6 @@
       N, T, internal::IsAProtocolMessage<T>::value>(x));
 }
 
-#if !((GTEST_GCC_VER_ && GTEST_GCC_VER_ < 40000) || GTEST_OS_SYMBIAN)
-// This overload allows SetArgPointee() to accept a string literal.
-// GCC prior to the version 4.0 and Symbian C++ compiler cannot distinguish
-// this overload from the templated version and emit a compile error.
 template <size_t N>
 PolymorphicAction<
   internal::SetArgumentPointeeAction<N, const char*, false> >
@@ -2106,7 +1856,6 @@
   return MakePolymorphicAction(internal::SetArgumentPointeeAction<
       N, const wchar_t*, false>(p));
 }
-#endif
 
 // The following version is DEPRECATED.
 template <size_t N, typename T>
@@ -2136,24 +1885,38 @@
 
 #endif  // !GTEST_OS_WINDOWS_MOBILE
 
-// Various overloads for InvokeWithoutArgs().
+// Various overloads for Invoke().
+
+// Legacy function.
+// Actions can now be implicitly constructed from callables. No need to create
+// wrapper objects.
+// This function exists for backwards compatibility.
+template <typename FunctionImpl>
+typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
+  return std::forward<FunctionImpl>(function_impl);
+}
+
+// Creates an action that invokes the given method on the given object
+// with the mock function's arguments.
+template <class Class, typename MethodPtr>
+internal::InvokeMethodAction<Class, MethodPtr> Invoke(Class* obj_ptr,
+                                                      MethodPtr method_ptr) {
+  return {obj_ptr, method_ptr};
+}
 
 // Creates an action that invokes 'function_impl' with no argument.
 template <typename FunctionImpl>
-PolymorphicAction<internal::InvokeWithoutArgsAction<FunctionImpl> >
+internal::InvokeWithoutArgsAction<typename std::decay<FunctionImpl>::type>
 InvokeWithoutArgs(FunctionImpl function_impl) {
-  return MakePolymorphicAction(
-      internal::InvokeWithoutArgsAction<FunctionImpl>(function_impl));
+  return {std::move(function_impl)};
 }
 
 // Creates an action that invokes the given method on the given object
 // with no argument.
 template <class Class, typename MethodPtr>
-PolymorphicAction<internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> >
-InvokeWithoutArgs(Class* obj_ptr, MethodPtr method_ptr) {
-  return MakePolymorphicAction(
-      internal::InvokeMethodWithoutArgsAction<Class, MethodPtr>(
-          obj_ptr, method_ptr));
+internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> InvokeWithoutArgs(
+    Class* obj_ptr, MethodPtr method_ptr) {
+  return {obj_ptr, method_ptr};
 }
 
 // Creates an action that performs an_action and throws away its
@@ -2171,13 +1934,21 @@
 // where Base is a base class of Derived, just write:
 //
 //   ByRef<const Base>(derived)
+//
+// N.B. ByRef is redundant with std::ref, std::cref and std::reference_wrapper.
+// However, it may still be used for consistency with ByMove().
 template <typename T>
-inline internal::ReferenceWrapper<T> ByRef(T& l_value) {  // NOLINT
-  return internal::ReferenceWrapper<T>(l_value);
+inline ::std::reference_wrapper<T> ByRef(T& l_value) {  // NOLINT
+  return ::std::reference_wrapper<T>(l_value);
 }
 
 }  // namespace testing
 
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+
 #endif  // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
 // Copyright 2007, Google Inc.
 // All rights reserved.
@@ -2207,8 +1978,7 @@
 // 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: wan@google.com (Zhanyong Wan)
+
 
 // Google Mock - a framework for writing C++ mock classes.
 //
@@ -2216,12 +1986,18 @@
 // cardinalities can be defined by the user implementing the
 // CardinalityInterface interface if necessary.
 
+// GOOGLETEST_CM0002 DO NOT DELETE
+
 #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
 #define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
 
 #include <limits.h>
+#include <memory>
 #include <ostream>  // NOLINT
 
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
 namespace testing {
 
 // To implement a cardinality Foo, define:
@@ -2256,9 +2032,8 @@
 
 // A Cardinality is a copyable and IMMUTABLE (except by assignment)
 // object that specifies how many times a mock function is expected to
-// be called.  The implementation of Cardinality is just a linked_ptr
-// to const CardinalityInterface, so copying is fairly cheap.
-// Don't inherit from Cardinality!
+// be called.  The implementation of Cardinality is just a std::shared_ptr
+// to const CardinalityInterface. Don't inherit from Cardinality!
 class GTEST_API_ Cardinality {
  public:
   // Constructs a null cardinality.  Needed for storing Cardinality
@@ -2298,7 +2073,7 @@
                                         ::std::ostream* os);
 
  private:
-  internal::linked_ptr<const CardinalityInterface> impl_;
+  std::shared_ptr<const CardinalityInterface> impl_;
 };
 
 // Creates a cardinality that allows at least n calls.
@@ -2323,8 +2098,15 @@
 
 }  // namespace testing
 
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251
+
 #endif  // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
-// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
+#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_  // NOLINT
+#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_  // NOLINT
+
+// This file was GENERATED by command:
+//     pump.py gmock-generated-function-mockers.h.pump
+// DO NOT EDIT BY HAND!!!
 
 // Copyright 2007, Google Inc.
 // All rights reserved.
@@ -2354,467 +2136,7874 @@
 // 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.
+
+
+// Google Mock - a framework for writing C++ mock classes.
 //
-// Author: wan@google.com (Zhanyong Wan)
+// This file implements function mockers of various arities.
+
+// GOOGLETEST_CM0002 DO NOT DELETE
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
+
+#include <functional>
+#include <utility>
+
+// Copyright 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.
+
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements the ON_CALL() and EXPECT_CALL() macros.
+//
+// A user can use the ON_CALL() macro to specify the default action of
+// a mock method.  The syntax is:
+//
+//   ON_CALL(mock_object, Method(argument-matchers))
+//       .With(multi-argument-matcher)
+//       .WillByDefault(action);
+//
+//  where the .With() clause is optional.
+//
+// A user can use the EXPECT_CALL() macro to specify an expectation on
+// a mock method.  The syntax is:
+//
+//   EXPECT_CALL(mock_object, Method(argument-matchers))
+//       .With(multi-argument-matchers)
+//       .Times(cardinality)
+//       .InSequence(sequences)
+//       .After(expectations)
+//       .WillOnce(action)
+//       .WillRepeatedly(action)
+//       .RetiresOnSaturation();
+//
+// where all clauses are optional, and .InSequence()/.After()/
+// .WillOnce() can appear any number of times.
+
+// GOOGLETEST_CM0002 DO NOT DELETE
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
+
+#include <map>
+#include <memory>
+#include <set>
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+// Copyright 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.
+
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements some commonly used argument matchers.  More
+// matchers can be defined by the user implementing the
+// MatcherInterface<T> interface if necessary.
+//
+// See googletest/include/gtest/gtest-matchers.h for the definition of class
+// Matcher, class MatcherInterface, and others.
+
+// GOOGLETEST_CM0002 DO NOT DELETE
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
+
+#include <math.h>
+#include <algorithm>
+#include <initializer_list>
+#include <iterator>
+#include <limits>
+#include <memory>
+#include <ostream>  // NOLINT
+#include <sstream>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(
+    4251 5046 /* class A needs to have dll-interface to be used by clients of
+                 class B */
+    /* Symbol involving type with internal linkage not defined */)
+
+namespace testing {
+
+// To implement a matcher Foo for type T, define:
+//   1. a class FooMatcherImpl that implements the
+//      MatcherInterface<T> interface, and
+//   2. a factory function that creates a Matcher<T> object from a
+//      FooMatcherImpl*.
+//
+// The two-level delegation design makes it possible to allow a user
+// to write "v" instead of "Eq(v)" where a Matcher is expected, which
+// is impossible if we pass matchers by pointers.  It also eases
+// ownership management as Matcher objects can now be copied like
+// plain values.
+
+// A match result listener that stores the explanation in a string.
+class StringMatchResultListener : public MatchResultListener {
+ public:
+  StringMatchResultListener() : MatchResultListener(&ss_) {}
+
+  // Returns the explanation accumulated so far.
+  std::string str() const { return ss_.str(); }
+
+  // Clears the explanation accumulated so far.
+  void Clear() { ss_.str(""); }
+
+ private:
+  ::std::stringstream ss_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(StringMatchResultListener);
+};
+
+// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
+// and MUST NOT BE USED IN USER CODE!!!
+namespace internal {
+
+// The MatcherCastImpl class template is a helper for implementing
+// MatcherCast().  We need this helper in order to partially
+// specialize the implementation of MatcherCast() (C++ allows
+// class/struct templates to be partially specialized, but not
+// function templates.).
+
+// This general version is used when MatcherCast()'s argument is a
+// polymorphic matcher (i.e. something that can be converted to a
+// Matcher but is not one yet; for example, Eq(value)) or a value (for
+// example, "hello").
+template <typename T, typename M>
+class MatcherCastImpl {
+ public:
+  static Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
+    // M can be a polymorphic matcher, in which case we want to use
+    // its conversion operator to create Matcher<T>.  Or it can be a value
+    // that should be passed to the Matcher<T>'s constructor.
+    //
+    // We can't call Matcher<T>(polymorphic_matcher_or_value) when M is a
+    // polymorphic matcher because it'll be ambiguous if T has an implicit
+    // constructor from M (this usually happens when T has an implicit
+    // constructor from any type).
+    //
+    // It won't work to unconditionally implict_cast
+    // polymorphic_matcher_or_value to Matcher<T> because it won't trigger
+    // a user-defined conversion from M to T if one exists (assuming M is
+    // a value).
+    return CastImpl(
+        polymorphic_matcher_or_value,
+        BooleanConstant<
+            std::is_convertible<M, Matcher<T> >::value>(),
+        BooleanConstant<
+            std::is_convertible<M, T>::value>());
+  }
+
+ private:
+  template <bool Ignore>
+  static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value,
+                             BooleanConstant<true> /* convertible_to_matcher */,
+                             BooleanConstant<Ignore>) {
+    // M is implicitly convertible to Matcher<T>, which means that either
+    // M is a polymorphic matcher or Matcher<T> has an implicit constructor
+    // from M.  In both cases using the implicit conversion will produce a
+    // matcher.
+    //
+    // Even if T has an implicit constructor from M, it won't be called because
+    // creating Matcher<T> would require a chain of two user-defined conversions
+    // (first to create T from M and then to create Matcher<T> from T).
+    return polymorphic_matcher_or_value;
+  }
+
+  // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
+  // matcher. It's a value of a type implicitly convertible to T. Use direct
+  // initialization to create a matcher.
+  static Matcher<T> CastImpl(
+      const M& value, BooleanConstant<false> /* convertible_to_matcher */,
+      BooleanConstant<true> /* convertible_to_T */) {
+    return Matcher<T>(ImplicitCast_<T>(value));
+  }
+
+  // M can't be implicitly converted to either Matcher<T> or T. Attempt to use
+  // polymorphic matcher Eq(value) in this case.
+  //
+  // Note that we first attempt to perform an implicit cast on the value and
+  // only fall back to the polymorphic Eq() matcher afterwards because the
+  // latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end
+  // which might be undefined even when Rhs is implicitly convertible to Lhs
+  // (e.g. std::pair<const int, int> vs. std::pair<int, int>).
+  //
+  // We don't define this method inline as we need the declaration of Eq().
+  static Matcher<T> CastImpl(
+      const M& value, BooleanConstant<false> /* convertible_to_matcher */,
+      BooleanConstant<false> /* convertible_to_T */);
+};
+
+// This more specialized version is used when MatcherCast()'s argument
+// is already a Matcher.  This only compiles when type T can be
+// statically converted to type U.
+template <typename T, typename U>
+class MatcherCastImpl<T, Matcher<U> > {
+ public:
+  static Matcher<T> Cast(const Matcher<U>& source_matcher) {
+    return Matcher<T>(new Impl(source_matcher));
+  }
+
+ private:
+  class Impl : public MatcherInterface<T> {
+   public:
+    explicit Impl(const Matcher<U>& source_matcher)
+        : source_matcher_(source_matcher) {}
+
+    // We delegate the matching logic to the source matcher.
+    bool MatchAndExplain(T x, MatchResultListener* listener) const override {
+      using FromType = typename std::remove_cv<typename std::remove_pointer<
+          typename std::remove_reference<T>::type>::type>::type;
+      using ToType = typename std::remove_cv<typename std::remove_pointer<
+          typename std::remove_reference<U>::type>::type>::type;
+      // Do not allow implicitly converting base*/& to derived*/&.
+      static_assert(
+          // Do not trigger if only one of them is a pointer. That implies a
+          // regular conversion and not a down_cast.
+          (std::is_pointer<typename std::remove_reference<T>::type>::value !=
+           std::is_pointer<typename std::remove_reference<U>::type>::value) ||
+              std::is_same<FromType, ToType>::value ||
+              !std::is_base_of<FromType, ToType>::value,
+          "Can't implicitly convert from <base> to <derived>");
+
+      return source_matcher_.MatchAndExplain(static_cast<U>(x), listener);
+    }
+
+    void DescribeTo(::std::ostream* os) const override {
+      source_matcher_.DescribeTo(os);
+    }
+
+    void DescribeNegationTo(::std::ostream* os) const override {
+      source_matcher_.DescribeNegationTo(os);
+    }
+
+   private:
+    const Matcher<U> source_matcher_;
+
+    GTEST_DISALLOW_ASSIGN_(Impl);
+  };
+};
+
+// This even more specialized version is used for efficiently casting
+// a matcher to its own type.
+template <typename T>
+class MatcherCastImpl<T, Matcher<T> > {
+ public:
+  static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }
+};
+
+}  // namespace internal
+
+// In order to be safe and clear, casting between different matcher
+// types is done explicitly via MatcherCast<T>(m), which takes a
+// matcher m and returns a Matcher<T>.  It compiles only when T can be
+// statically converted to the argument type of m.
+template <typename T, typename M>
+inline Matcher<T> MatcherCast(const M& matcher) {
+  return internal::MatcherCastImpl<T, M>::Cast(matcher);
+}
+
+// Implements SafeMatcherCast().
+//
+// FIXME: The intermediate SafeMatcherCastImpl class was introduced as a
+// workaround for a compiler bug, and can now be removed.
+template <typename T>
+class SafeMatcherCastImpl {
+ public:
+  // This overload handles polymorphic matchers and values only since
+  // monomorphic matchers are handled by the next one.
+  template <typename M>
+  static inline Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
+    return internal::MatcherCastImpl<T, M>::Cast(polymorphic_matcher_or_value);
+  }
+
+  // This overload handles monomorphic matchers.
+  //
+  // In general, if type T can be implicitly converted to type U, we can
+  // safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is
+  // contravariant): just keep a copy of the original Matcher<U>, convert the
+  // argument from type T to U, and then pass it to the underlying Matcher<U>.
+  // The only exception is when U is a reference and T is not, as the
+  // underlying Matcher<U> may be interested in the argument's address, which
+  // is not preserved in the conversion from T to U.
+  template <typename U>
+  static inline Matcher<T> Cast(const Matcher<U>& matcher) {
+    // Enforce that T can be implicitly converted to U.
+    GTEST_COMPILE_ASSERT_((std::is_convertible<T, U>::value),
+                          "T must be implicitly convertible to U");
+    // Enforce that we are not converting a non-reference type T to a reference
+    // type U.
+    GTEST_COMPILE_ASSERT_(
+        internal::is_reference<T>::value || !internal::is_reference<U>::value,
+        cannot_convert_non_reference_arg_to_reference);
+    // In case both T and U are arithmetic types, enforce that the
+    // conversion is not lossy.
+    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT;
+    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU;
+    const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther;
+    const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther;
+    GTEST_COMPILE_ASSERT_(
+        kTIsOther || kUIsOther ||
+        (internal::LosslessArithmeticConvertible<RawT, RawU>::value),
+        conversion_of_arithmetic_types_must_be_lossless);
+    return MatcherCast<T>(matcher);
+  }
+};
+
+template <typename T, typename M>
+inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher) {
+  return SafeMatcherCastImpl<T>::Cast(polymorphic_matcher);
+}
+
+// A<T>() returns a matcher that matches any value of type T.
+template <typename T>
+Matcher<T> A();
+
+// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
+// and MUST NOT BE USED IN USER CODE!!!
+namespace internal {
+
+// If the explanation is not empty, prints it to the ostream.
+inline void PrintIfNotEmpty(const std::string& explanation,
+                            ::std::ostream* os) {
+  if (explanation != "" && os != nullptr) {
+    *os << ", " << explanation;
+  }
+}
+
+// Returns true if the given type name is easy to read by a human.
+// This is used to decide whether printing the type of a value might
+// be helpful.
+inline bool IsReadableTypeName(const std::string& type_name) {
+  // We consider a type name readable if it's short or doesn't contain
+  // a template or function type.
+  return (type_name.length() <= 20 ||
+          type_name.find_first_of("<(") == std::string::npos);
+}
+
+// Matches the value against the given matcher, prints the value and explains
+// the match result to the listener. Returns the match result.
+// 'listener' must not be NULL.
+// Value cannot be passed by const reference, because some matchers take a
+// non-const argument.
+template <typename Value, typename T>
+bool MatchPrintAndExplain(Value& value, const Matcher<T>& matcher,
+                          MatchResultListener* listener) {
+  if (!listener->IsInterested()) {
+    // If the listener is not interested, we do not need to construct the
+    // inner explanation.
+    return matcher.Matches(value);
+  }
+
+  StringMatchResultListener inner_listener;
+  const bool match = matcher.MatchAndExplain(value, &inner_listener);
+
+  UniversalPrint(value, listener->stream());
+#if GTEST_HAS_RTTI
+  const std::string& type_name = GetTypeName<Value>();
+  if (IsReadableTypeName(type_name))
+    *listener->stream() << " (of type " << type_name << ")";
+#endif
+  PrintIfNotEmpty(inner_listener.str(), listener->stream());
+
+  return match;
+}
+
+// An internal helper class for doing compile-time loop on a tuple's
+// fields.
+template <size_t N>
+class TuplePrefix {
+ public:
+  // TuplePrefix<N>::Matches(matcher_tuple, value_tuple) returns true
+  // iff the first N fields of matcher_tuple matches the first N
+  // fields of value_tuple, respectively.
+  template <typename MatcherTuple, typename ValueTuple>
+  static bool Matches(const MatcherTuple& matcher_tuple,
+                      const ValueTuple& value_tuple) {
+    return TuplePrefix<N - 1>::Matches(matcher_tuple, value_tuple) &&
+           std::get<N - 1>(matcher_tuple).Matches(std::get<N - 1>(value_tuple));
+  }
+
+  // TuplePrefix<N>::ExplainMatchFailuresTo(matchers, values, os)
+  // describes failures in matching the first N fields of matchers
+  // against the first N fields of values.  If there is no failure,
+  // nothing will be streamed to os.
+  template <typename MatcherTuple, typename ValueTuple>
+  static void ExplainMatchFailuresTo(const MatcherTuple& matchers,
+                                     const ValueTuple& values,
+                                     ::std::ostream* os) {
+    // First, describes failures in the first N - 1 fields.
+    TuplePrefix<N - 1>::ExplainMatchFailuresTo(matchers, values, os);
+
+    // Then describes the failure (if any) in the (N - 1)-th (0-based)
+    // field.
+    typename std::tuple_element<N - 1, MatcherTuple>::type matcher =
+        std::get<N - 1>(matchers);
+    typedef typename std::tuple_element<N - 1, ValueTuple>::type Value;
+    const Value& value = std::get<N - 1>(values);
+    StringMatchResultListener listener;
+    if (!matcher.MatchAndExplain(value, &listener)) {
+      *os << "  Expected arg #" << N - 1 << ": ";
+      std::get<N - 1>(matchers).DescribeTo(os);
+      *os << "\n           Actual: ";
+      // We remove the reference in type Value to prevent the
+      // universal printer from printing the address of value, which
+      // isn't interesting to the user most of the time.  The
+      // matcher's MatchAndExplain() method handles the case when
+      // the address is interesting.
+      internal::UniversalPrint(value, os);
+      PrintIfNotEmpty(listener.str(), os);
+      *os << "\n";
+    }
+  }
+};
+
+// The base case.
+template <>
+class TuplePrefix<0> {
+ public:
+  template <typename MatcherTuple, typename ValueTuple>
+  static bool Matches(const MatcherTuple& /* matcher_tuple */,
+                      const ValueTuple& /* value_tuple */) {
+    return true;
+  }
+
+  template <typename MatcherTuple, typename ValueTuple>
+  static void ExplainMatchFailuresTo(const MatcherTuple& /* matchers */,
+                                     const ValueTuple& /* values */,
+                                     ::std::ostream* /* os */) {}
+};
+
+// TupleMatches(matcher_tuple, value_tuple) returns true iff all
+// matchers in matcher_tuple match the corresponding fields in
+// value_tuple.  It is a compiler error if matcher_tuple and
+// value_tuple have different number of fields or incompatible field
+// types.
+template <typename MatcherTuple, typename ValueTuple>
+bool TupleMatches(const MatcherTuple& matcher_tuple,
+                  const ValueTuple& value_tuple) {
+  // Makes sure that matcher_tuple and value_tuple have the same
+  // number of fields.
+  GTEST_COMPILE_ASSERT_(std::tuple_size<MatcherTuple>::value ==
+                            std::tuple_size<ValueTuple>::value,
+                        matcher_and_value_have_different_numbers_of_fields);
+  return TuplePrefix<std::tuple_size<ValueTuple>::value>::Matches(matcher_tuple,
+                                                                  value_tuple);
+}
+
+// Describes failures in matching matchers against values.  If there
+// is no failure, nothing will be streamed to os.
+template <typename MatcherTuple, typename ValueTuple>
+void ExplainMatchFailureTupleTo(const MatcherTuple& matchers,
+                                const ValueTuple& values,
+                                ::std::ostream* os) {
+  TuplePrefix<std::tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo(
+      matchers, values, os);
+}
+
+// TransformTupleValues and its helper.
+//
+// TransformTupleValuesHelper hides the internal machinery that
+// TransformTupleValues uses to implement a tuple traversal.
+template <typename Tuple, typename Func, typename OutIter>
+class TransformTupleValuesHelper {
+ private:
+  typedef ::std::tuple_size<Tuple> TupleSize;
+
+ public:
+  // For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'.
+  // Returns the final value of 'out' in case the caller needs it.
+  static OutIter Run(Func f, const Tuple& t, OutIter out) {
+    return IterateOverTuple<Tuple, TupleSize::value>()(f, t, out);
+  }
+
+ private:
+  template <typename Tup, size_t kRemainingSize>
+  struct IterateOverTuple {
+    OutIter operator() (Func f, const Tup& t, OutIter out) const {
+      *out++ = f(::std::get<TupleSize::value - kRemainingSize>(t));
+      return IterateOverTuple<Tup, kRemainingSize - 1>()(f, t, out);
+    }
+  };
+  template <typename Tup>
+  struct IterateOverTuple<Tup, 0> {
+    OutIter operator() (Func /* f */, const Tup& /* t */, OutIter out) const {
+      return out;
+    }
+  };
+};
+
+// Successively invokes 'f(element)' on each element of the tuple 't',
+// appending each result to the 'out' iterator. Returns the final value
+// of 'out'.
+template <typename Tuple, typename Func, typename OutIter>
+OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) {
+  return TransformTupleValuesHelper<Tuple, Func, OutIter>::Run(f, t, out);
+}
+
+// Implements A<T>().
+template <typename T>
+class AnyMatcherImpl : public MatcherInterface<const T&> {
+ public:
+  bool MatchAndExplain(const T& /* x */,
+                       MatchResultListener* /* listener */) const override {
+    return true;
+  }
+  void DescribeTo(::std::ostream* os) const override { *os << "is anything"; }
+  void DescribeNegationTo(::std::ostream* os) const override {
+    // This is mostly for completeness' safe, as it's not very useful
+    // to write Not(A<bool>()).  However we cannot completely rule out
+    // such a possibility, and it doesn't hurt to be prepared.
+    *os << "never matches";
+  }
+};
+
+// Implements _, a matcher that matches any value of any
+// type.  This is a polymorphic matcher, so we need a template type
+// conversion operator to make it appearing as a Matcher<T> for any
+// type T.
+class AnythingMatcher {
+ public:
+  template <typename T>
+  operator Matcher<T>() const { return A<T>(); }
+};
+
+// Implements the polymorphic IsNull() matcher, which matches any raw or smart
+// pointer that is NULL.
+class IsNullMatcher {
+ public:
+  template <typename Pointer>
+  bool MatchAndExplain(const Pointer& p,
+                       MatchResultListener* /* listener */) const {
+    return p == nullptr;
+  }
+
+  void DescribeTo(::std::ostream* os) const { *os << "is NULL"; }
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "isn't NULL";
+  }
+};
+
+// Implements the polymorphic NotNull() matcher, which matches any raw or smart
+// pointer that is not NULL.
+class NotNullMatcher {
+ public:
+  template <typename Pointer>
+  bool MatchAndExplain(const Pointer& p,
+                       MatchResultListener* /* listener */) const {
+    return p != nullptr;
+  }
+
+  void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; }
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "is NULL";
+  }
+};
+
+// Ref(variable) matches any argument that is a reference to
+// 'variable'.  This matcher is polymorphic as it can match any
+// super type of the type of 'variable'.
+//
+// The RefMatcher template class implements Ref(variable).  It can
+// only be instantiated with a reference type.  This prevents a user
+// from mistakenly using Ref(x) to match a non-reference function
+// argument.  For example, the following will righteously cause a
+// compiler error:
+//
+//   int n;
+//   Matcher<int> m1 = Ref(n);   // This won't compile.
+//   Matcher<int&> m2 = Ref(n);  // This will compile.
+template <typename T>
+class RefMatcher;
+
+template <typename T>
+class RefMatcher<T&> {
+  // Google Mock is a generic framework and thus needs to support
+  // mocking any function types, including those that take non-const
+  // reference arguments.  Therefore the template parameter T (and
+  // Super below) can be instantiated to either a const type or a
+  // non-const type.
+ public:
+  // RefMatcher() takes a T& instead of const T&, as we want the
+  // compiler to catch using Ref(const_value) as a matcher for a
+  // non-const reference.
+  explicit RefMatcher(T& x) : object_(x) {}  // NOLINT
+
+  template <typename Super>
+  operator Matcher<Super&>() const {
+    // By passing object_ (type T&) to Impl(), which expects a Super&,
+    // we make sure that Super is a super type of T.  In particular,
+    // this catches using Ref(const_value) as a matcher for a
+    // non-const reference, as you cannot implicitly convert a const
+    // reference to a non-const reference.
+    return MakeMatcher(new Impl<Super>(object_));
+  }
+
+ private:
+  template <typename Super>
+  class Impl : public MatcherInterface<Super&> {
+   public:
+    explicit Impl(Super& x) : object_(x) {}  // NOLINT
+
+    // MatchAndExplain() takes a Super& (as opposed to const Super&)
+    // in order to match the interface MatcherInterface<Super&>.
+    bool MatchAndExplain(Super& x,
+                         MatchResultListener* listener) const override {
+      *listener << "which is located @" << static_cast<const void*>(&x);
+      return &x == &object_;
+    }
+
+    void DescribeTo(::std::ostream* os) const override {
+      *os << "references the variable ";
+      UniversalPrinter<Super&>::Print(object_, os);
+    }
+
+    void DescribeNegationTo(::std::ostream* os) const override {
+      *os << "does not reference the variable ";
+      UniversalPrinter<Super&>::Print(object_, os);
+    }
+
+   private:
+    const Super& object_;
+
+    GTEST_DISALLOW_ASSIGN_(Impl);
+  };
+
+  T& object_;
+
+  GTEST_DISALLOW_ASSIGN_(RefMatcher);
+};
+
+// Polymorphic helper functions for narrow and wide string matchers.
+inline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) {
+  return String::CaseInsensitiveCStringEquals(lhs, rhs);
+}
+
+inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs,
+                                         const wchar_t* rhs) {
+  return String::CaseInsensitiveWideCStringEquals(lhs, rhs);
+}
+
+// String comparison for narrow or wide strings that can have embedded NUL
+// characters.
+template <typename StringType>
+bool CaseInsensitiveStringEquals(const StringType& s1,
+                                 const StringType& s2) {
+  // Are the heads equal?
+  if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) {
+    return false;
+  }
+
+  // Skip the equal heads.
+  const typename StringType::value_type nul = 0;
+  const size_t i1 = s1.find(nul), i2 = s2.find(nul);
+
+  // Are we at the end of either s1 or s2?
+  if (i1 == StringType::npos || i2 == StringType::npos) {
+    return i1 == i2;
+  }
+
+  // Are the tails equal?
+  return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1));
+}
+
+// String matchers.
+
+// Implements equality-based string matchers like StrEq, StrCaseNe, and etc.
+template <typename StringType>
+class StrEqualityMatcher {
+ public:
+  StrEqualityMatcher(const StringType& str, bool expect_eq,
+                     bool case_sensitive)
+      : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {}
+
+#if GTEST_HAS_ABSL
+  bool MatchAndExplain(const absl::string_view& s,
+                       MatchResultListener* listener) const {
+    // This should fail to compile if absl::string_view is used with wide
+    // strings.
+    const StringType& str = string(s);
+    return MatchAndExplain(str, listener);
+  }
+#endif  // GTEST_HAS_ABSL
+
+  // Accepts pointer types, particularly:
+  //   const char*
+  //   char*
+  //   const wchar_t*
+  //   wchar_t*
+  template <typename CharType>
+  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
+    if (s == nullptr) {
+      return !expect_eq_;
+    }
+    return MatchAndExplain(StringType(s), listener);
+  }
+
+  // Matches anything that can convert to StringType.
+  //
+  // This is a template, not just a plain function with const StringType&,
+  // because absl::string_view has some interfering non-explicit constructors.
+  template <typename MatcheeStringType>
+  bool MatchAndExplain(const MatcheeStringType& s,
+                       MatchResultListener* /* listener */) const {
+    const StringType& s2(s);
+    const bool eq = case_sensitive_ ? s2 == string_ :
+        CaseInsensitiveStringEquals(s2, string_);
+    return expect_eq_ == eq;
+  }
+
+  void DescribeTo(::std::ostream* os) const {
+    DescribeToHelper(expect_eq_, os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const {
+    DescribeToHelper(!expect_eq_, os);
+  }
+
+ private:
+  void DescribeToHelper(bool expect_eq, ::std::ostream* os) const {
+    *os << (expect_eq ? "is " : "isn't ");
+    *os << "equal to ";
+    if (!case_sensitive_) {
+      *os << "(ignoring case) ";
+    }
+    UniversalPrint(string_, os);
+  }
+
+  const StringType string_;
+  const bool expect_eq_;
+  const bool case_sensitive_;
+
+  GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher);
+};
+
+// Implements the polymorphic HasSubstr(substring) matcher, which
+// can be used as a Matcher<T> as long as T can be converted to a
+// string.
+template <typename StringType>
+class HasSubstrMatcher {
+ public:
+  explicit HasSubstrMatcher(const StringType& substring)
+      : substring_(substring) {}
+
+#if GTEST_HAS_ABSL
+  bool MatchAndExplain(const absl::string_view& s,
+                       MatchResultListener* listener) const {
+    // This should fail to compile if absl::string_view is used with wide
+    // strings.
+    const StringType& str = string(s);
+    return MatchAndExplain(str, listener);
+  }
+#endif  // GTEST_HAS_ABSL
+
+  // Accepts pointer types, particularly:
+  //   const char*
+  //   char*
+  //   const wchar_t*
+  //   wchar_t*
+  template <typename CharType>
+  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
+    return s != nullptr && MatchAndExplain(StringType(s), listener);
+  }
+
+  // Matches anything that can convert to StringType.
+  //
+  // This is a template, not just a plain function with const StringType&,
+  // because absl::string_view has some interfering non-explicit constructors.
+  template <typename MatcheeStringType>
+  bool MatchAndExplain(const MatcheeStringType& s,
+                       MatchResultListener* /* listener */) const {
+    const StringType& s2(s);
+    return s2.find(substring_) != StringType::npos;
+  }
+
+  // Describes what this matcher matches.
+  void DescribeTo(::std::ostream* os) const {
+    *os << "has substring ";
+    UniversalPrint(substring_, os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "has no substring ";
+    UniversalPrint(substring_, os);
+  }
+
+ private:
+  const StringType substring_;
+
+  GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher);
+};
+
+// Implements the polymorphic StartsWith(substring) matcher, which
+// can be used as a Matcher<T> as long as T can be converted to a
+// string.
+template <typename StringType>
+class StartsWithMatcher {
+ public:
+  explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {
+  }
+
+#if GTEST_HAS_ABSL
+  bool MatchAndExplain(const absl::string_view& s,
+                       MatchResultListener* listener) const {
+    // This should fail to compile if absl::string_view is used with wide
+    // strings.
+    const StringType& str = string(s);
+    return MatchAndExplain(str, listener);
+  }
+#endif  // GTEST_HAS_ABSL
+
+  // Accepts pointer types, particularly:
+  //   const char*
+  //   char*
+  //   const wchar_t*
+  //   wchar_t*
+  template <typename CharType>
+  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
+    return s != nullptr && MatchAndExplain(StringType(s), listener);
+  }
+
+  // Matches anything that can convert to StringType.
+  //
+  // This is a template, not just a plain function with const StringType&,
+  // because absl::string_view has some interfering non-explicit constructors.
+  template <typename MatcheeStringType>
+  bool MatchAndExplain(const MatcheeStringType& s,
+                       MatchResultListener* /* listener */) const {
+    const StringType& s2(s);
+    return s2.length() >= prefix_.length() &&
+        s2.substr(0, prefix_.length()) == prefix_;
+  }
+
+  void DescribeTo(::std::ostream* os) const {
+    *os << "starts with ";
+    UniversalPrint(prefix_, os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "doesn't start with ";
+    UniversalPrint(prefix_, os);
+  }
+
+ private:
+  const StringType prefix_;
+
+  GTEST_DISALLOW_ASSIGN_(StartsWithMatcher);
+};
+
+// Implements the polymorphic EndsWith(substring) matcher, which
+// can be used as a Matcher<T> as long as T can be converted to a
+// string.
+template <typename StringType>
+class EndsWithMatcher {
+ public:
+  explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {}
+
+#if GTEST_HAS_ABSL
+  bool MatchAndExplain(const absl::string_view& s,
+                       MatchResultListener* listener) const {
+    // This should fail to compile if absl::string_view is used with wide
+    // strings.
+    const StringType& str = string(s);
+    return MatchAndExplain(str, listener);
+  }
+#endif  // GTEST_HAS_ABSL
+
+  // Accepts pointer types, particularly:
+  //   const char*
+  //   char*
+  //   const wchar_t*
+  //   wchar_t*
+  template <typename CharType>
+  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
+    return s != nullptr && MatchAndExplain(StringType(s), listener);
+  }
+
+  // Matches anything that can convert to StringType.
+  //
+  // This is a template, not just a plain function with const StringType&,
+  // because absl::string_view has some interfering non-explicit constructors.
+  template <typename MatcheeStringType>
+  bool MatchAndExplain(const MatcheeStringType& s,
+                       MatchResultListener* /* listener */) const {
+    const StringType& s2(s);
+    return s2.length() >= suffix_.length() &&
+        s2.substr(s2.length() - suffix_.length()) == suffix_;
+  }
+
+  void DescribeTo(::std::ostream* os) const {
+    *os << "ends with ";
+    UniversalPrint(suffix_, os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "doesn't end with ";
+    UniversalPrint(suffix_, os);
+  }
+
+ private:
+  const StringType suffix_;
+
+  GTEST_DISALLOW_ASSIGN_(EndsWithMatcher);
+};
+
+// Implements a matcher that compares the two fields of a 2-tuple
+// using one of the ==, <=, <, etc, operators.  The two fields being
+// compared don't have to have the same type.
+//
+// The matcher defined here is polymorphic (for example, Eq() can be
+// used to match a std::tuple<int, short>, a std::tuple<const long&, double>,
+// etc).  Therefore we use a template type conversion operator in the
+// implementation.
+template <typename D, typename Op>
+class PairMatchBase {
+ public:
+  template <typename T1, typename T2>
+  operator Matcher<::std::tuple<T1, T2>>() const {
+    return Matcher<::std::tuple<T1, T2>>(new Impl<const ::std::tuple<T1, T2>&>);
+  }
+  template <typename T1, typename T2>
+  operator Matcher<const ::std::tuple<T1, T2>&>() const {
+    return MakeMatcher(new Impl<const ::std::tuple<T1, T2>&>);
+  }
+
+ private:
+  static ::std::ostream& GetDesc(::std::ostream& os) {  // NOLINT
+    return os << D::Desc();
+  }
+
+  template <typename Tuple>
+  class Impl : public MatcherInterface<Tuple> {
+   public:
+    bool MatchAndExplain(Tuple args,
+                         MatchResultListener* /* listener */) const override {
+      return Op()(::std::get<0>(args), ::std::get<1>(args));
+    }
+    void DescribeTo(::std::ostream* os) const override {
+      *os << "are " << GetDesc;
+    }
+    void DescribeNegationTo(::std::ostream* os) const override {
+      *os << "aren't " << GetDesc;
+    }
+  };
+};
+
+class Eq2Matcher : public PairMatchBase<Eq2Matcher, AnyEq> {
+ public:
+  static const char* Desc() { return "an equal pair"; }
+};
+class Ne2Matcher : public PairMatchBase<Ne2Matcher, AnyNe> {
+ public:
+  static const char* Desc() { return "an unequal pair"; }
+};
+class Lt2Matcher : public PairMatchBase<Lt2Matcher, AnyLt> {
+ public:
+  static const char* Desc() { return "a pair where the first < the second"; }
+};
+class Gt2Matcher : public PairMatchBase<Gt2Matcher, AnyGt> {
+ public:
+  static const char* Desc() { return "a pair where the first > the second"; }
+};
+class Le2Matcher : public PairMatchBase<Le2Matcher, AnyLe> {
+ public:
+  static const char* Desc() { return "a pair where the first <= the second"; }
+};
+class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> {
+ public:
+  static const char* Desc() { return "a pair where the first >= the second"; }
+};
+
+// Implements the Not(...) matcher for a particular argument type T.
+// We do not nest it inside the NotMatcher class template, as that
+// will prevent different instantiations of NotMatcher from sharing
+// the same NotMatcherImpl<T> class.
+template <typename T>
+class NotMatcherImpl : public MatcherInterface<const T&> {
+ public:
+  explicit NotMatcherImpl(const Matcher<T>& matcher)
+      : matcher_(matcher) {}
+
+  bool MatchAndExplain(const T& x,
+                       MatchResultListener* listener) const override {
+    return !matcher_.MatchAndExplain(x, listener);
+  }
+
+  void DescribeTo(::std::ostream* os) const override {
+    matcher_.DescribeNegationTo(os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const override {
+    matcher_.DescribeTo(os);
+  }
+
+ private:
+  const Matcher<T> matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(NotMatcherImpl);
+};
+
+// Implements the Not(m) matcher, which matches a value that doesn't
+// match matcher m.
+template <typename InnerMatcher>
+class NotMatcher {
+ public:
+  explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {}
+
+  // This template type conversion operator allows Not(m) to be used
+  // to match any type m can match.
+  template <typename T>
+  operator Matcher<T>() const {
+    return Matcher<T>(new NotMatcherImpl<T>(SafeMatcherCast<T>(matcher_)));
+  }
+
+ private:
+  InnerMatcher matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(NotMatcher);
+};
+
+// Implements the AllOf(m1, m2) matcher for a particular argument type
+// T. We do not nest it inside the BothOfMatcher class template, as
+// that will prevent different instantiations of BothOfMatcher from
+// sharing the same BothOfMatcherImpl<T> class.
+template <typename T>
+class AllOfMatcherImpl : public MatcherInterface<const T&> {
+ public:
+  explicit AllOfMatcherImpl(std::vector<Matcher<T> > matchers)
+      : matchers_(std::move(matchers)) {}
+
+  void DescribeTo(::std::ostream* os) const override {
+    *os << "(";
+    for (size_t i = 0; i < matchers_.size(); ++i) {
+      if (i != 0) *os << ") and (";
+      matchers_[i].DescribeTo(os);
+    }
+    *os << ")";
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const override {
+    *os << "(";
+    for (size_t i = 0; i < matchers_.size(); ++i) {
+      if (i != 0) *os << ") or (";
+      matchers_[i].DescribeNegationTo(os);
+    }
+    *os << ")";
+  }
+
+  bool MatchAndExplain(const T& x,
+                       MatchResultListener* listener) const override {
+    // If either matcher1_ or matcher2_ doesn't match x, we only need
+    // to explain why one of them fails.
+    std::string all_match_result;
+
+    for (size_t i = 0; i < matchers_.size(); ++i) {
+      StringMatchResultListener slistener;
+      if (matchers_[i].MatchAndExplain(x, &slistener)) {
+        if (all_match_result.empty()) {
+          all_match_result = slistener.str();
+        } else {
+          std::string result = slistener.str();
+          if (!result.empty()) {
+            all_match_result += ", and ";
+            all_match_result += result;
+          }
+        }
+      } else {
+        *listener << slistener.str();
+        return false;
+      }
+    }
+
+    // Otherwise we need to explain why *both* of them match.
+    *listener << all_match_result;
+    return true;
+  }
+
+ private:
+  const std::vector<Matcher<T> > matchers_;
+
+  GTEST_DISALLOW_ASSIGN_(AllOfMatcherImpl);
+};
+
+// VariadicMatcher is used for the variadic implementation of
+// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...).
+// CombiningMatcher<T> is used to recursively combine the provided matchers
+// (of type Args...).
+template <template <typename T> class CombiningMatcher, typename... Args>
+class VariadicMatcher {
+ public:
+  VariadicMatcher(const Args&... matchers)  // NOLINT
+      : matchers_(matchers...) {
+    static_assert(sizeof...(Args) > 0, "Must have at least one matcher.");
+  }
+
+  // This template type conversion operator allows an
+  // VariadicMatcher<Matcher1, Matcher2...> object to match any type that
+  // all of the provided matchers (Matcher1, Matcher2, ...) can match.
+  template <typename T>
+  operator Matcher<T>() const {
+    std::vector<Matcher<T> > values;
+    CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>());
+    return Matcher<T>(new CombiningMatcher<T>(std::move(values)));
+  }
+
+ private:
+  template <typename T, size_t I>
+  void CreateVariadicMatcher(std::vector<Matcher<T> >* values,
+                             std::integral_constant<size_t, I>) const {
+    values->push_back(SafeMatcherCast<T>(std::get<I>(matchers_)));
+    CreateVariadicMatcher<T>(values, std::integral_constant<size_t, I + 1>());
+  }
+
+  template <typename T>
+  void CreateVariadicMatcher(
+      std::vector<Matcher<T> >*,
+      std::integral_constant<size_t, sizeof...(Args)>) const {}
+
+  std::tuple<Args...> matchers_;
+
+  GTEST_DISALLOW_ASSIGN_(VariadicMatcher);
+};
+
+template <typename... Args>
+using AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>;
+
+// Implements the AnyOf(m1, m2) matcher for a particular argument type
+// T.  We do not nest it inside the AnyOfMatcher class template, as
+// that will prevent different instantiations of AnyOfMatcher from
+// sharing the same EitherOfMatcherImpl<T> class.
+template <typename T>
+class AnyOfMatcherImpl : public MatcherInterface<const T&> {
+ public:
+  explicit AnyOfMatcherImpl(std::vector<Matcher<T> > matchers)
+      : matchers_(std::move(matchers)) {}
+
+  void DescribeTo(::std::ostream* os) const override {
+    *os << "(";
+    for (size_t i = 0; i < matchers_.size(); ++i) {
+      if (i != 0) *os << ") or (";
+      matchers_[i].DescribeTo(os);
+    }
+    *os << ")";
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const override {
+    *os << "(";
+    for (size_t i = 0; i < matchers_.size(); ++i) {
+      if (i != 0) *os << ") and (";
+      matchers_[i].DescribeNegationTo(os);
+    }
+    *os << ")";
+  }
+
+  bool MatchAndExplain(const T& x,
+                       MatchResultListener* listener) const override {
+    std::string no_match_result;
+
+    // If either matcher1_ or matcher2_ matches x, we just need to
+    // explain why *one* of them matches.
+    for (size_t i = 0; i < matchers_.size(); ++i) {
+      StringMatchResultListener slistener;
+      if (matchers_[i].MatchAndExplain(x, &slistener)) {
+        *listener << slistener.str();
+        return true;
+      } else {
+        if (no_match_result.empty()) {
+          no_match_result = slistener.str();
+        } else {
+          std::string result = slistener.str();
+          if (!result.empty()) {
+            no_match_result += ", and ";
+            no_match_result += result;
+          }
+        }
+      }
+    }
+
+    // Otherwise we need to explain why *both* of them fail.
+    *listener << no_match_result;
+    return false;
+  }
+
+ private:
+  const std::vector<Matcher<T> > matchers_;
+
+  GTEST_DISALLOW_ASSIGN_(AnyOfMatcherImpl);
+};
+
+// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...).
+template <typename... Args>
+using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>;
+
+// Wrapper for implementation of Any/AllOfArray().
+template <template <class> class MatcherImpl, typename T>
+class SomeOfArrayMatcher {
+ public:
+  // Constructs the matcher from a sequence of element values or
+  // element matchers.
+  template <typename Iter>
+  SomeOfArrayMatcher(Iter first, Iter last) : matchers_(first, last) {}
+
+  template <typename U>
+  operator Matcher<U>() const {  // NOLINT
+    using RawU = typename std::decay<U>::type;
+    std::vector<Matcher<RawU>> matchers;
+    for (const auto& matcher : matchers_) {
+      matchers.push_back(MatcherCast<RawU>(matcher));
+    }
+    return Matcher<U>(new MatcherImpl<RawU>(std::move(matchers)));
+  }
+
+ private:
+  const ::std::vector<T> matchers_;
+
+  GTEST_DISALLOW_ASSIGN_(SomeOfArrayMatcher);
+};
+
+template <typename T>
+using AllOfArrayMatcher = SomeOfArrayMatcher<AllOfMatcherImpl, T>;
+
+template <typename T>
+using AnyOfArrayMatcher = SomeOfArrayMatcher<AnyOfMatcherImpl, T>;
+
+// Used for implementing Truly(pred), which turns a predicate into a
+// matcher.
+template <typename Predicate>
+class TrulyMatcher {
+ public:
+  explicit TrulyMatcher(Predicate pred) : predicate_(pred) {}
+
+  // This method template allows Truly(pred) to be used as a matcher
+  // for type T where T is the argument type of predicate 'pred'.  The
+  // argument is passed by reference as the predicate may be
+  // interested in the address of the argument.
+  template <typename T>
+  bool MatchAndExplain(T& x,  // NOLINT
+                       MatchResultListener* /* listener */) const {
+    // Without the if-statement, MSVC sometimes warns about converting
+    // a value to bool (warning 4800).
+    //
+    // We cannot write 'return !!predicate_(x);' as that doesn't work
+    // when predicate_(x) returns a class convertible to bool but
+    // having no operator!().
+    if (predicate_(x))
+      return true;
+    return false;
+  }
+
+  void DescribeTo(::std::ostream* os) const {
+    *os << "satisfies the given predicate";
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "doesn't satisfy the given predicate";
+  }
+
+ private:
+  Predicate predicate_;
+
+  GTEST_DISALLOW_ASSIGN_(TrulyMatcher);
+};
+
+// Used for implementing Matches(matcher), which turns a matcher into
+// a predicate.
+template <typename M>
+class MatcherAsPredicate {
+ public:
+  explicit MatcherAsPredicate(M matcher) : matcher_(matcher) {}
+
+  // This template operator() allows Matches(m) to be used as a
+  // predicate on type T where m is a matcher on type T.
+  //
+  // The argument x is passed by reference instead of by value, as
+  // some matcher may be interested in its address (e.g. as in
+  // Matches(Ref(n))(x)).
+  template <typename T>
+  bool operator()(const T& x) const {
+    // We let matcher_ commit to a particular type here instead of
+    // when the MatcherAsPredicate object was constructed.  This
+    // allows us to write Matches(m) where m is a polymorphic matcher
+    // (e.g. Eq(5)).
+    //
+    // If we write Matcher<T>(matcher_).Matches(x) here, it won't
+    // compile when matcher_ has type Matcher<const T&>; if we write
+    // Matcher<const T&>(matcher_).Matches(x) here, it won't compile
+    // when matcher_ has type Matcher<T>; if we just write
+    // matcher_.Matches(x), it won't compile when matcher_ is
+    // polymorphic, e.g. Eq(5).
+    //
+    // MatcherCast<const T&>() is necessary for making the code work
+    // in all of the above situations.
+    return MatcherCast<const T&>(matcher_).Matches(x);
+  }
+
+ private:
+  M matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(MatcherAsPredicate);
+};
+
+// For implementing ASSERT_THAT() and EXPECT_THAT().  The template
+// argument M must be a type that can be converted to a matcher.
+template <typename M>
+class PredicateFormatterFromMatcher {
+ public:
+  explicit PredicateFormatterFromMatcher(M m) : matcher_(std::move(m)) {}
+
+  // This template () operator allows a PredicateFormatterFromMatcher
+  // object to act as a predicate-formatter suitable for using with
+  // Google Test's EXPECT_PRED_FORMAT1() macro.
+  template <typename T>
+  AssertionResult operator()(const char* value_text, const T& x) const {
+    // We convert matcher_ to a Matcher<const T&> *now* instead of
+    // when the PredicateFormatterFromMatcher object was constructed,
+    // as matcher_ may be polymorphic (e.g. NotNull()) and we won't
+    // know which type to instantiate it to until we actually see the
+    // type of x here.
+    //
+    // We write SafeMatcherCast<const T&>(matcher_) instead of
+    // Matcher<const T&>(matcher_), as the latter won't compile when
+    // matcher_ has type Matcher<T> (e.g. An<int>()).
+    // We don't write MatcherCast<const T&> either, as that allows
+    // potentially unsafe downcasting of the matcher argument.
+    const Matcher<const T&> matcher = SafeMatcherCast<const T&>(matcher_);
+
+    // The expected path here is that the matcher should match (i.e. that most
+    // tests pass) so optimize for this case.
+    if (matcher.Matches(x)) {
+      return AssertionSuccess();
+    }
+
+    ::std::stringstream ss;
+    ss << "Value of: " << value_text << "\n"
+       << "Expected: ";
+    matcher.DescribeTo(&ss);
+
+    // Rerun the matcher to "PrintAndExain" the failure.
+    StringMatchResultListener listener;
+    if (MatchPrintAndExplain(x, matcher, &listener)) {
+      ss << "\n  The matcher failed on the initial attempt; but passed when "
+            "rerun to generate the explanation.";
+    }
+    ss << "\n  Actual: " << listener.str();
+    return AssertionFailure() << ss.str();
+  }
+
+ private:
+  const M matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(PredicateFormatterFromMatcher);
+};
+
+// A helper function for converting a matcher to a predicate-formatter
+// without the user needing to explicitly write the type.  This is
+// used for implementing ASSERT_THAT() and EXPECT_THAT().
+// Implementation detail: 'matcher' is received by-value to force decaying.
+template <typename M>
+inline PredicateFormatterFromMatcher<M>
+MakePredicateFormatterFromMatcher(M matcher) {
+  return PredicateFormatterFromMatcher<M>(std::move(matcher));
+}
+
+// Implements the polymorphic floating point equality matcher, which matches
+// two float values using ULP-based approximation or, optionally, a
+// user-specified epsilon.  The template is meant to be instantiated with
+// FloatType being either float or double.
+template <typename FloatType>
+class FloatingEqMatcher {
+ public:
+  // Constructor for FloatingEqMatcher.
+  // The matcher's input will be compared with expected.  The matcher treats two
+  // NANs as equal if nan_eq_nan is true.  Otherwise, under IEEE standards,
+  // equality comparisons between NANs will always return false.  We specify a
+  // negative max_abs_error_ term to indicate that ULP-based approximation will
+  // be used for comparison.
+  FloatingEqMatcher(FloatType expected, bool nan_eq_nan) :
+    expected_(expected), nan_eq_nan_(nan_eq_nan), max_abs_error_(-1) {
+  }
+
+  // Constructor that supports a user-specified max_abs_error that will be used
+  // for comparison instead of ULP-based approximation.  The max absolute
+  // should be non-negative.
+  FloatingEqMatcher(FloatType expected, bool nan_eq_nan,
+                    FloatType max_abs_error)
+      : expected_(expected),
+        nan_eq_nan_(nan_eq_nan),
+        max_abs_error_(max_abs_error) {
+    GTEST_CHECK_(max_abs_error >= 0)
+        << ", where max_abs_error is" << max_abs_error;
+  }
+
+  // Implements floating point equality matcher as a Matcher<T>.
+  template <typename T>
+  class Impl : public MatcherInterface<T> {
+   public:
+    Impl(FloatType expected, bool nan_eq_nan, FloatType max_abs_error)
+        : expected_(expected),
+          nan_eq_nan_(nan_eq_nan),
+          max_abs_error_(max_abs_error) {}
+
+    bool MatchAndExplain(T value,
+                         MatchResultListener* listener) const override {
+      const FloatingPoint<FloatType> actual(value), expected(expected_);
+
+      // Compares NaNs first, if nan_eq_nan_ is true.
+      if (actual.is_nan() || expected.is_nan()) {
+        if (actual.is_nan() && expected.is_nan()) {
+          return nan_eq_nan_;
+        }
+        // One is nan; the other is not nan.
+        return false;
+      }
+      if (HasMaxAbsError()) {
+        // We perform an equality check so that inf will match inf, regardless
+        // of error bounds.  If the result of value - expected_ would result in
+        // overflow or if either value is inf, the default result is infinity,
+        // which should only match if max_abs_error_ is also infinity.
+        if (value == expected_) {
+          return true;
+        }
+
+        const FloatType diff = value - expected_;
+        if (fabs(diff) <= max_abs_error_) {
+          return true;
+        }
+
+        if (listener->IsInterested()) {
+          *listener << "which is " << diff << " from " << expected_;
+        }
+        return false;
+      } else {
+        return actual.AlmostEquals(expected);
+      }
+    }
+
+    void DescribeTo(::std::ostream* os) const override {
+      // os->precision() returns the previously set precision, which we
+      // store to restore the ostream to its original configuration
+      // after outputting.
+      const ::std::streamsize old_precision = os->precision(
+          ::std::numeric_limits<FloatType>::digits10 + 2);
+      if (FloatingPoint<FloatType>(expected_).is_nan()) {
+        if (nan_eq_nan_) {
+          *os << "is NaN";
+        } else {
+          *os << "never matches";
+        }
+      } else {
+        *os << "is approximately " << expected_;
+        if (HasMaxAbsError()) {
+          *os << " (absolute error <= " << max_abs_error_ << ")";
+        }
+      }
+      os->precision(old_precision);
+    }
+
+    void DescribeNegationTo(::std::ostream* os) const override {
+      // As before, get original precision.
+      const ::std::streamsize old_precision = os->precision(
+          ::std::numeric_limits<FloatType>::digits10 + 2);
+      if (FloatingPoint<FloatType>(expected_).is_nan()) {
+        if (nan_eq_nan_) {
+          *os << "isn't NaN";
+        } else {
+          *os << "is anything";
+        }
+      } else {
+        *os << "isn't approximately " << expected_;
+        if (HasMaxAbsError()) {
+          *os << " (absolute error > " << max_abs_error_ << ")";
+        }
+      }
+      // Restore original precision.
+      os->precision(old_precision);
+    }
+
+   private:
+    bool HasMaxAbsError() const {
+      return max_abs_error_ >= 0;
+    }
+
+    const FloatType expected_;
+    const bool nan_eq_nan_;
+    // max_abs_error will be used for value comparison when >= 0.
+    const FloatType max_abs_error_;
+
+    GTEST_DISALLOW_ASSIGN_(Impl);
+  };
+
+  // The following 3 type conversion operators allow FloatEq(expected) and
+  // NanSensitiveFloatEq(expected) to be used as a Matcher<float>, a
+  // Matcher<const float&>, or a Matcher<float&>, but nothing else.
+  // (While Google's C++ coding style doesn't allow arguments passed
+  // by non-const reference, we may see them in code not conforming to
+  // the style.  Therefore Google Mock needs to support them.)
+  operator Matcher<FloatType>() const {
+    return MakeMatcher(
+        new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_));
+  }
+
+  operator Matcher<const FloatType&>() const {
+    return MakeMatcher(
+        new Impl<const FloatType&>(expected_, nan_eq_nan_, max_abs_error_));
+  }
+
+  operator Matcher<FloatType&>() const {
+    return MakeMatcher(
+        new Impl<FloatType&>(expected_, nan_eq_nan_, max_abs_error_));
+  }
+
+ private:
+  const FloatType expected_;
+  const bool nan_eq_nan_;
+  // max_abs_error will be used for value comparison when >= 0.
+  const FloatType max_abs_error_;
+
+  GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher);
+};
+
+// A 2-tuple ("binary") wrapper around FloatingEqMatcher:
+// FloatingEq2Matcher() matches (x, y) by matching FloatingEqMatcher(x, false)
+// against y, and FloatingEq2Matcher(e) matches FloatingEqMatcher(x, false, e)
+// against y. The former implements "Eq", the latter "Near". At present, there
+// is no version that compares NaNs as equal.
+template <typename FloatType>
+class FloatingEq2Matcher {
+ public:
+  FloatingEq2Matcher() { Init(-1, false); }
+
+  explicit FloatingEq2Matcher(bool nan_eq_nan) { Init(-1, nan_eq_nan); }
+
+  explicit FloatingEq2Matcher(FloatType max_abs_error) {
+    Init(max_abs_error, false);
+  }
+
+  FloatingEq2Matcher(FloatType max_abs_error, bool nan_eq_nan) {
+    Init(max_abs_error, nan_eq_nan);
+  }
+
+  template <typename T1, typename T2>
+  operator Matcher<::std::tuple<T1, T2>>() const {
+    return MakeMatcher(
+        new Impl<::std::tuple<T1, T2>>(max_abs_error_, nan_eq_nan_));
+  }
+  template <typename T1, typename T2>
+  operator Matcher<const ::std::tuple<T1, T2>&>() const {
+    return MakeMatcher(
+        new Impl<const ::std::tuple<T1, T2>&>(max_abs_error_, nan_eq_nan_));
+  }
+
+ private:
+  static ::std::ostream& GetDesc(::std::ostream& os) {  // NOLINT
+    return os << "an almost-equal pair";
+  }
+
+  template <typename Tuple>
+  class Impl : public MatcherInterface<Tuple> {
+   public:
+    Impl(FloatType max_abs_error, bool nan_eq_nan) :
+        max_abs_error_(max_abs_error),
+        nan_eq_nan_(nan_eq_nan) {}
+
+    bool MatchAndExplain(Tuple args,
+                         MatchResultListener* listener) const override {
+      if (max_abs_error_ == -1) {
+        FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_);
+        return static_cast<Matcher<FloatType>>(fm).MatchAndExplain(
+            ::std::get<1>(args), listener);
+      } else {
+        FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_,
+                                        max_abs_error_);
+        return static_cast<Matcher<FloatType>>(fm).MatchAndExplain(
+            ::std::get<1>(args), listener);
+      }
+    }
+    void DescribeTo(::std::ostream* os) const override {
+      *os << "are " << GetDesc;
+    }
+    void DescribeNegationTo(::std::ostream* os) const override {
+      *os << "aren't " << GetDesc;
+    }
+
+   private:
+    FloatType max_abs_error_;
+    const bool nan_eq_nan_;
+  };
+
+  void Init(FloatType max_abs_error_val, bool nan_eq_nan_val) {
+    max_abs_error_ = max_abs_error_val;
+    nan_eq_nan_ = nan_eq_nan_val;
+  }
+  FloatType max_abs_error_;
+  bool nan_eq_nan_;
+};
+
+// Implements the Pointee(m) matcher for matching a pointer whose
+// pointee matches matcher m.  The pointer can be either raw or smart.
+template <typename InnerMatcher>
+class PointeeMatcher {
+ public:
+  explicit PointeeMatcher(const InnerMatcher& matcher) : matcher_(matcher) {}
+
+  // This type conversion operator template allows Pointee(m) to be
+  // used as a matcher for any pointer type whose pointee type is
+  // compatible with the inner matcher, where type Pointer can be
+  // either a raw pointer or a smart pointer.
+  //
+  // The reason we do this instead of relying on
+  // MakePolymorphicMatcher() is that the latter is not flexible
+  // enough for implementing the DescribeTo() method of Pointee().
+  template <typename Pointer>
+  operator Matcher<Pointer>() const {
+    return Matcher<Pointer>(new Impl<const Pointer&>(matcher_));
+  }
+
+ private:
+  // The monomorphic implementation that works for a particular pointer type.
+  template <typename Pointer>
+  class Impl : public MatcherInterface<Pointer> {
+   public:
+    typedef typename PointeeOf<GTEST_REMOVE_CONST_(  // NOLINT
+        GTEST_REMOVE_REFERENCE_(Pointer))>::type Pointee;
+
+    explicit Impl(const InnerMatcher& matcher)
+        : matcher_(MatcherCast<const Pointee&>(matcher)) {}
+
+    void DescribeTo(::std::ostream* os) const override {
+      *os << "points to a value that ";
+      matcher_.DescribeTo(os);
+    }
+
+    void DescribeNegationTo(::std::ostream* os) const override {
+      *os << "does not point to a value that ";
+      matcher_.DescribeTo(os);
+    }
+
+    bool MatchAndExplain(Pointer pointer,
+                         MatchResultListener* listener) const override {
+      if (GetRawPointer(pointer) == nullptr) return false;
+
+      *listener << "which points to ";
+      return MatchPrintAndExplain(*pointer, matcher_, listener);
+    }
+
+   private:
+    const Matcher<const Pointee&> matcher_;
+
+    GTEST_DISALLOW_ASSIGN_(Impl);
+  };
+
+  const InnerMatcher matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(PointeeMatcher);
+};
+
+#if GTEST_HAS_RTTI
+// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or
+// reference that matches inner_matcher when dynamic_cast<T> is applied.
+// The result of dynamic_cast<To> is forwarded to the inner matcher.
+// If To is a pointer and the cast fails, the inner matcher will receive NULL.
+// If To is a reference and the cast fails, this matcher returns false
+// immediately.
+template <typename To>
+class WhenDynamicCastToMatcherBase {
+ public:
+  explicit WhenDynamicCastToMatcherBase(const Matcher<To>& matcher)
+      : matcher_(matcher) {}
+
+  void DescribeTo(::std::ostream* os) const {
+    GetCastTypeDescription(os);
+    matcher_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const {
+    GetCastTypeDescription(os);
+    matcher_.DescribeNegationTo(os);
+  }
+
+ protected:
+  const Matcher<To> matcher_;
+
+  static std::string GetToName() {
+    return GetTypeName<To>();
+  }
+
+ private:
+  static void GetCastTypeDescription(::std::ostream* os) {
+    *os << "when dynamic_cast to " << GetToName() << ", ";
+  }
+
+  GTEST_DISALLOW_ASSIGN_(WhenDynamicCastToMatcherBase);
+};
+
+// Primary template.
+// To is a pointer. Cast and forward the result.
+template <typename To>
+class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> {
+ public:
+  explicit WhenDynamicCastToMatcher(const Matcher<To>& matcher)
+      : WhenDynamicCastToMatcherBase<To>(matcher) {}
+
+  template <typename From>
+  bool MatchAndExplain(From from, MatchResultListener* listener) const {
+    To to = dynamic_cast<To>(from);
+    return MatchPrintAndExplain(to, this->matcher_, listener);
+  }
+};
+
+// Specialize for references.
+// In this case we return false if the dynamic_cast fails.
+template <typename To>
+class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> {
+ public:
+  explicit WhenDynamicCastToMatcher(const Matcher<To&>& matcher)
+      : WhenDynamicCastToMatcherBase<To&>(matcher) {}
+
+  template <typename From>
+  bool MatchAndExplain(From& from, MatchResultListener* listener) const {
+    // We don't want an std::bad_cast here, so do the cast with pointers.
+    To* to = dynamic_cast<To*>(&from);
+    if (to == nullptr) {
+      *listener << "which cannot be dynamic_cast to " << this->GetToName();
+      return false;
+    }
+    return MatchPrintAndExplain(*to, this->matcher_, listener);
+  }
+};
+#endif  // GTEST_HAS_RTTI
+
+// Implements the Field() matcher for matching a field (i.e. member
+// variable) of an object.
+template <typename Class, typename FieldType>
+class FieldMatcher {
+ public:
+  FieldMatcher(FieldType Class::*field,
+               const Matcher<const FieldType&>& matcher)
+      : field_(field), matcher_(matcher), whose_field_("whose given field ") {}
+
+  FieldMatcher(const std::string& field_name, FieldType Class::*field,
+               const Matcher<const FieldType&>& matcher)
+      : field_(field),
+        matcher_(matcher),
+        whose_field_("whose field `" + field_name + "` ") {}
+
+  void DescribeTo(::std::ostream* os) const {
+    *os << "is an object " << whose_field_;
+    matcher_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "is an object " << whose_field_;
+    matcher_.DescribeNegationTo(os);
+  }
+
+  template <typename T>
+  bool MatchAndExplain(const T& value, MatchResultListener* listener) const {
+    // FIXME: The dispatch on std::is_pointer was introduced as a workaround for
+    // a compiler bug, and can now be removed.
+    return MatchAndExplainImpl(
+        typename std::is_pointer<GTEST_REMOVE_CONST_(T)>::type(), value,
+        listener);
+  }
+
+ private:
+  bool MatchAndExplainImpl(std::false_type /* is_not_pointer */,
+                           const Class& obj,
+                           MatchResultListener* listener) const {
+    *listener << whose_field_ << "is ";
+    return MatchPrintAndExplain(obj.*field_, matcher_, listener);
+  }
+
+  bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p,
+                           MatchResultListener* listener) const {
+    if (p == nullptr) return false;
+
+    *listener << "which points to an object ";
+    // Since *p has a field, it must be a class/struct/union type and
+    // thus cannot be a pointer.  Therefore we pass false_type() as
+    // the first argument.
+    return MatchAndExplainImpl(std::false_type(), *p, listener);
+  }
+
+  const FieldType Class::*field_;
+  const Matcher<const FieldType&> matcher_;
+
+  // Contains either "whose given field " if the name of the field is unknown
+  // or "whose field `name_of_field` " if the name is known.
+  const std::string whose_field_;
+
+  GTEST_DISALLOW_ASSIGN_(FieldMatcher);
+};
+
+// Implements the Property() matcher for matching a property
+// (i.e. return value of a getter method) of an object.
+//
+// Property is a const-qualified member function of Class returning
+// PropertyType.
+template <typename Class, typename PropertyType, typename Property>
+class PropertyMatcher {
+ public:
+  typedef const PropertyType& RefToConstProperty;
+
+  PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher)
+      : property_(property),
+        matcher_(matcher),
+        whose_property_("whose given property ") {}
+
+  PropertyMatcher(const std::string& property_name, Property property,
+                  const Matcher<RefToConstProperty>& matcher)
+      : property_(property),
+        matcher_(matcher),
+        whose_property_("whose property `" + property_name + "` ") {}
+
+  void DescribeTo(::std::ostream* os) const {
+    *os << "is an object " << whose_property_;
+    matcher_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "is an object " << whose_property_;
+    matcher_.DescribeNegationTo(os);
+  }
+
+  template <typename T>
+  bool MatchAndExplain(const T&value, MatchResultListener* listener) const {
+    return MatchAndExplainImpl(
+        typename std::is_pointer<GTEST_REMOVE_CONST_(T)>::type(), value,
+        listener);
+  }
+
+ private:
+  bool MatchAndExplainImpl(std::false_type /* is_not_pointer */,
+                           const Class& obj,
+                           MatchResultListener* listener) const {
+    *listener << whose_property_ << "is ";
+    // Cannot pass the return value (for example, int) to MatchPrintAndExplain,
+    // which takes a non-const reference as argument.
+    RefToConstProperty result = (obj.*property_)();
+    return MatchPrintAndExplain(result, matcher_, listener);
+  }
+
+  bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p,
+                           MatchResultListener* listener) const {
+    if (p == nullptr) return false;
+
+    *listener << "which points to an object ";
+    // Since *p has a property method, it must be a class/struct/union
+    // type and thus cannot be a pointer.  Therefore we pass
+    // false_type() as the first argument.
+    return MatchAndExplainImpl(std::false_type(), *p, listener);
+  }
+
+  Property property_;
+  const Matcher<RefToConstProperty> matcher_;
+
+  // Contains either "whose given property " if the name of the property is
+  // unknown or "whose property `name_of_property` " if the name is known.
+  const std::string whose_property_;
+
+  GTEST_DISALLOW_ASSIGN_(PropertyMatcher);
+};
+
+// Type traits specifying various features of different functors for ResultOf.
+// The default template specifies features for functor objects.
+template <typename Functor>
+struct CallableTraits {
+  typedef Functor StorageType;
+
+  static void CheckIsValid(Functor /* functor */) {}
+
+  template <typename T>
+  static auto Invoke(Functor f, T arg) -> decltype(f(arg)) { return f(arg); }
+};
+
+// Specialization for function pointers.
+template <typename ArgType, typename ResType>
+struct CallableTraits<ResType(*)(ArgType)> {
+  typedef ResType ResultType;
+  typedef ResType(*StorageType)(ArgType);
+
+  static void CheckIsValid(ResType(*f)(ArgType)) {
+    GTEST_CHECK_(f != nullptr)
+        << "NULL function pointer is passed into ResultOf().";
+  }
+  template <typename T>
+  static ResType Invoke(ResType(*f)(ArgType), T arg) {
+    return (*f)(arg);
+  }
+};
+
+// Implements the ResultOf() matcher for matching a return value of a
+// unary function of an object.
+template <typename Callable, typename InnerMatcher>
+class ResultOfMatcher {
+ public:
+  ResultOfMatcher(Callable callable, InnerMatcher matcher)
+      : callable_(std::move(callable)), matcher_(std::move(matcher)) {
+    CallableTraits<Callable>::CheckIsValid(callable_);
+  }
+
+  template <typename T>
+  operator Matcher<T>() const {
+    return Matcher<T>(new Impl<T>(callable_, matcher_));
+  }
+
+ private:
+  typedef typename CallableTraits<Callable>::StorageType CallableStorageType;
+
+  template <typename T>
+  class Impl : public MatcherInterface<T> {
+    using ResultType = decltype(CallableTraits<Callable>::template Invoke<T>(
+        std::declval<CallableStorageType>(), std::declval<T>()));
+
+   public:
+    template <typename M>
+    Impl(const CallableStorageType& callable, const M& matcher)
+        : callable_(callable), matcher_(MatcherCast<ResultType>(matcher)) {}
+
+    void DescribeTo(::std::ostream* os) const override {
+      *os << "is mapped by the given callable to a value that ";
+      matcher_.DescribeTo(os);
+    }
+
+    void DescribeNegationTo(::std::ostream* os) const override {
+      *os << "is mapped by the given callable to a value that ";
+      matcher_.DescribeNegationTo(os);
+    }
+
+    bool MatchAndExplain(T obj, MatchResultListener* listener) const override {
+      *listener << "which is mapped by the given callable to ";
+      // Cannot pass the return value directly to MatchPrintAndExplain, which
+      // takes a non-const reference as argument.
+      // Also, specifying template argument explicitly is needed because T could
+      // be a non-const reference (e.g. Matcher<Uncopyable&>).
+      ResultType result =
+          CallableTraits<Callable>::template Invoke<T>(callable_, obj);
+      return MatchPrintAndExplain(result, matcher_, listener);
+    }
+
+   private:
+    // Functors often define operator() as non-const method even though
+    // they are actually stateless. But we need to use them even when
+    // 'this' is a const pointer. It's the user's responsibility not to
+    // use stateful callables with ResultOf(), which doesn't guarantee
+    // how many times the callable will be invoked.
+    mutable CallableStorageType callable_;
+    const Matcher<ResultType> matcher_;
+
+    GTEST_DISALLOW_ASSIGN_(Impl);
+  };  // class Impl
+
+  const CallableStorageType callable_;
+  const InnerMatcher matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(ResultOfMatcher);
+};
+
+// Implements a matcher that checks the size of an STL-style container.
+template <typename SizeMatcher>
+class SizeIsMatcher {
+ public:
+  explicit SizeIsMatcher(const SizeMatcher& size_matcher)
+       : size_matcher_(size_matcher) {
+  }
+
+  template <typename Container>
+  operator Matcher<Container>() const {
+    return Matcher<Container>(new Impl<const Container&>(size_matcher_));
+  }
+
+  template <typename Container>
+  class Impl : public MatcherInterface<Container> {
+   public:
+    using SizeType = decltype(std::declval<Container>().size());
+    explicit Impl(const SizeMatcher& size_matcher)
+        : size_matcher_(MatcherCast<SizeType>(size_matcher)) {}
+
+    void DescribeTo(::std::ostream* os) const override {
+      *os << "size ";
+      size_matcher_.DescribeTo(os);
+    }
+    void DescribeNegationTo(::std::ostream* os) const override {
+      *os << "size ";
+      size_matcher_.DescribeNegationTo(os);
+    }
+
+    bool MatchAndExplain(Container container,
+                         MatchResultListener* listener) const override {
+      SizeType size = container.size();
+      StringMatchResultListener size_listener;
+      const bool result = size_matcher_.MatchAndExplain(size, &size_listener);
+      *listener
+          << "whose size " << size << (result ? " matches" : " doesn't match");
+      PrintIfNotEmpty(size_listener.str(), listener->stream());
+      return result;
+    }
+
+   private:
+    const Matcher<SizeType> size_matcher_;
+    GTEST_DISALLOW_ASSIGN_(Impl);
+  };
+
+ private:
+  const SizeMatcher size_matcher_;
+  GTEST_DISALLOW_ASSIGN_(SizeIsMatcher);
+};
+
+// Implements a matcher that checks the begin()..end() distance of an STL-style
+// container.
+template <typename DistanceMatcher>
+class BeginEndDistanceIsMatcher {
+ public:
+  explicit BeginEndDistanceIsMatcher(const DistanceMatcher& distance_matcher)
+      : distance_matcher_(distance_matcher) {}
+
+  template <typename Container>
+  operator Matcher<Container>() const {
+    return Matcher<Container>(new Impl<const Container&>(distance_matcher_));
+  }
+
+  template <typename Container>
+  class Impl : public MatcherInterface<Container> {
+   public:
+    typedef internal::StlContainerView<
+        GTEST_REMOVE_REFERENCE_AND_CONST_(Container)> ContainerView;
+    typedef typename std::iterator_traits<
+        typename ContainerView::type::const_iterator>::difference_type
+        DistanceType;
+    explicit Impl(const DistanceMatcher& distance_matcher)
+        : distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {}
+
+    void DescribeTo(::std::ostream* os) const override {
+      *os << "distance between begin() and end() ";
+      distance_matcher_.DescribeTo(os);
+    }
+    void DescribeNegationTo(::std::ostream* os) const override {
+      *os << "distance between begin() and end() ";
+      distance_matcher_.DescribeNegationTo(os);
+    }
+
+    bool MatchAndExplain(Container container,
+                         MatchResultListener* listener) const override {
+      using std::begin;
+      using std::end;
+      DistanceType distance = std::distance(begin(container), end(container));
+      StringMatchResultListener distance_listener;
+      const bool result =
+          distance_matcher_.MatchAndExplain(distance, &distance_listener);
+      *listener << "whose distance between begin() and end() " << distance
+                << (result ? " matches" : " doesn't match");
+      PrintIfNotEmpty(distance_listener.str(), listener->stream());
+      return result;
+    }
+
+   private:
+    const Matcher<DistanceType> distance_matcher_;
+    GTEST_DISALLOW_ASSIGN_(Impl);
+  };
+
+ private:
+  const DistanceMatcher distance_matcher_;
+  GTEST_DISALLOW_ASSIGN_(BeginEndDistanceIsMatcher);
+};
+
+// Implements an equality matcher for any STL-style container whose elements
+// support ==. This matcher is like Eq(), but its failure explanations provide
+// more detailed information that is useful when the container is used as a set.
+// The failure message reports elements that are in one of the operands but not
+// the other. The failure messages do not report duplicate or out-of-order
+// elements in the containers (which don't properly matter to sets, but can
+// occur if the containers are vectors or lists, for example).
+//
+// Uses the container's const_iterator, value_type, operator ==,
+// begin(), and end().
+template <typename Container>
+class ContainerEqMatcher {
+ public:
+  typedef internal::StlContainerView<Container> View;
+  typedef typename View::type StlContainer;
+  typedef typename View::const_reference StlContainerReference;
+
+  // We make a copy of expected in case the elements in it are modified
+  // after this matcher is created.
+  explicit ContainerEqMatcher(const Container& expected)
+      : expected_(View::Copy(expected)) {
+    // Makes sure the user doesn't instantiate this class template
+    // with a const or reference type.
+    (void)testing::StaticAssertTypeEq<Container,
+        GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>();
+  }
+
+  void DescribeTo(::std::ostream* os) const {
+    *os << "equals ";
+    UniversalPrint(expected_, os);
+  }
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "does not equal ";
+    UniversalPrint(expected_, os);
+  }
+
+  template <typename LhsContainer>
+  bool MatchAndExplain(const LhsContainer& lhs,
+                       MatchResultListener* listener) const {
+    // GTEST_REMOVE_CONST_() is needed to work around an MSVC 8.0 bug
+    // that causes LhsContainer to be a const type sometimes.
+    typedef internal::StlContainerView<GTEST_REMOVE_CONST_(LhsContainer)>
+        LhsView;
+    typedef typename LhsView::type LhsStlContainer;
+    StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
+    if (lhs_stl_container == expected_)
+      return true;
+
+    ::std::ostream* const os = listener->stream();
+    if (os != nullptr) {
+      // Something is different. Check for extra values first.
+      bool printed_header = false;
+      for (typename LhsStlContainer::const_iterator it =
+               lhs_stl_container.begin();
+           it != lhs_stl_container.end(); ++it) {
+        if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) ==
+            expected_.end()) {
+          if (printed_header) {
+            *os << ", ";
+          } else {
+            *os << "which has these unexpected elements: ";
+            printed_header = true;
+          }
+          UniversalPrint(*it, os);
+        }
+      }
+
+      // Now check for missing values.
+      bool printed_header2 = false;
+      for (typename StlContainer::const_iterator it = expected_.begin();
+           it != expected_.end(); ++it) {
+        if (internal::ArrayAwareFind(
+                lhs_stl_container.begin(), lhs_stl_container.end(), *it) ==
+            lhs_stl_container.end()) {
+          if (printed_header2) {
+            *os << ", ";
+          } else {
+            *os << (printed_header ? ",\nand" : "which")
+                << " doesn't have these expected elements: ";
+            printed_header2 = true;
+          }
+          UniversalPrint(*it, os);
+        }
+      }
+    }
+
+    return false;
+  }
+
+ private:
+  const StlContainer expected_;
+
+  GTEST_DISALLOW_ASSIGN_(ContainerEqMatcher);
+};
+
+// A comparator functor that uses the < operator to compare two values.
+struct LessComparator {
+  template <typename T, typename U>
+  bool operator()(const T& lhs, const U& rhs) const { return lhs < rhs; }
+};
+
+// Implements WhenSortedBy(comparator, container_matcher).
+template <typename Comparator, typename ContainerMatcher>
+class WhenSortedByMatcher {
+ public:
+  WhenSortedByMatcher(const Comparator& comparator,
+                      const ContainerMatcher& matcher)
+      : comparator_(comparator), matcher_(matcher) {}
+
+  template <typename LhsContainer>
+  operator Matcher<LhsContainer>() const {
+    return MakeMatcher(new Impl<LhsContainer>(comparator_, matcher_));
+  }
+
+  template <typename LhsContainer>
+  class Impl : public MatcherInterface<LhsContainer> {
+   public:
+    typedef internal::StlContainerView<
+         GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView;
+    typedef typename LhsView::type LhsStlContainer;
+    typedef typename LhsView::const_reference LhsStlContainerReference;
+    // Transforms std::pair<const Key, Value> into std::pair<Key, Value>
+    // so that we can match associative containers.
+    typedef typename RemoveConstFromKey<
+        typename LhsStlContainer::value_type>::type LhsValue;
+
+    Impl(const Comparator& comparator, const ContainerMatcher& matcher)
+        : comparator_(comparator), matcher_(matcher) {}
+
+    void DescribeTo(::std::ostream* os) const override {
+      *os << "(when sorted) ";
+      matcher_.DescribeTo(os);
+    }
+
+    void DescribeNegationTo(::std::ostream* os) const override {
+      *os << "(when sorted) ";
+      matcher_.DescribeNegationTo(os);
+    }
+
+    bool MatchAndExplain(LhsContainer lhs,
+                         MatchResultListener* listener) const override {
+      LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
+      ::std::vector<LhsValue> sorted_container(lhs_stl_container.begin(),
+                                               lhs_stl_container.end());
+      ::std::sort(
+           sorted_container.begin(), sorted_container.end(), comparator_);
+
+      if (!listener->IsInterested()) {
+        // If the listener is not interested, we do not need to
+        // construct the inner explanation.
+        return matcher_.Matches(sorted_container);
+      }
+
+      *listener << "which is ";
+      UniversalPrint(sorted_container, listener->stream());
+      *listener << " when sorted";
+
+      StringMatchResultListener inner_listener;
+      const bool match = matcher_.MatchAndExplain(sorted_container,
+                                                  &inner_listener);
+      PrintIfNotEmpty(inner_listener.str(), listener->stream());
+      return match;
+    }
+
+   private:
+    const Comparator comparator_;
+    const Matcher<const ::std::vector<LhsValue>&> matcher_;
+
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl);
+  };
+
+ private:
+  const Comparator comparator_;
+  const ContainerMatcher matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(WhenSortedByMatcher);
+};
+
+// Implements Pointwise(tuple_matcher, rhs_container).  tuple_matcher
+// must be able to be safely cast to Matcher<std::tuple<const T1&, const
+// T2&> >, where T1 and T2 are the types of elements in the LHS
+// container and the RHS container respectively.
+template <typename TupleMatcher, typename RhsContainer>
+class PointwiseMatcher {
+  GTEST_COMPILE_ASSERT_(
+      !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>::value,
+      use_UnorderedPointwise_with_hash_tables);
+
+ public:
+  typedef internal::StlContainerView<RhsContainer> RhsView;
+  typedef typename RhsView::type RhsStlContainer;
+  typedef typename RhsStlContainer::value_type RhsValue;
+
+  // Like ContainerEq, we make a copy of rhs in case the elements in
+  // it are modified after this matcher is created.
+  PointwiseMatcher(const TupleMatcher& tuple_matcher, const RhsContainer& rhs)
+      : tuple_matcher_(tuple_matcher), rhs_(RhsView::Copy(rhs)) {
+    // Makes sure the user doesn't instantiate this class template
+    // with a const or reference type.
+    (void)testing::StaticAssertTypeEq<RhsContainer,
+        GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>();
+  }
+
+  template <typename LhsContainer>
+  operator Matcher<LhsContainer>() const {
+    GTEST_COMPILE_ASSERT_(
+        !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value,
+        use_UnorderedPointwise_with_hash_tables);
+
+    return Matcher<LhsContainer>(
+        new Impl<const LhsContainer&>(tuple_matcher_, rhs_));
+  }
+
+  template <typename LhsContainer>
+  class Impl : public MatcherInterface<LhsContainer> {
+   public:
+    typedef internal::StlContainerView<
+         GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView;
+    typedef typename LhsView::type LhsStlContainer;
+    typedef typename LhsView::const_reference LhsStlContainerReference;
+    typedef typename LhsStlContainer::value_type LhsValue;
+    // We pass the LHS value and the RHS value to the inner matcher by
+    // reference, as they may be expensive to copy.  We must use tuple
+    // instead of pair here, as a pair cannot hold references (C++ 98,
+    // 20.2.2 [lib.pairs]).
+    typedef ::std::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg;
+
+    Impl(const TupleMatcher& tuple_matcher, const RhsStlContainer& rhs)
+        // mono_tuple_matcher_ holds a monomorphic version of the tuple matcher.
+        : mono_tuple_matcher_(SafeMatcherCast<InnerMatcherArg>(tuple_matcher)),
+          rhs_(rhs) {}
+
+    void DescribeTo(::std::ostream* os) const override {
+      *os << "contains " << rhs_.size()
+          << " values, where each value and its corresponding value in ";
+      UniversalPrinter<RhsStlContainer>::Print(rhs_, os);
+      *os << " ";
+      mono_tuple_matcher_.DescribeTo(os);
+    }
+    void DescribeNegationTo(::std::ostream* os) const override {
+      *os << "doesn't contain exactly " << rhs_.size()
+          << " values, or contains a value x at some index i"
+          << " where x and the i-th value of ";
+      UniversalPrint(rhs_, os);
+      *os << " ";
+      mono_tuple_matcher_.DescribeNegationTo(os);
+    }
+
+    bool MatchAndExplain(LhsContainer lhs,
+                         MatchResultListener* listener) const override {
+      LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
+      const size_t actual_size = lhs_stl_container.size();
+      if (actual_size != rhs_.size()) {
+        *listener << "which contains " << actual_size << " values";
+        return false;
+      }
+
+      typename LhsStlContainer::const_iterator left = lhs_stl_container.begin();
+      typename RhsStlContainer::const_iterator right = rhs_.begin();
+      for (size_t i = 0; i != actual_size; ++i, ++left, ++right) {
+        if (listener->IsInterested()) {
+          StringMatchResultListener inner_listener;
+          // Create InnerMatcherArg as a temporarily object to avoid it outlives
+          // *left and *right. Dereference or the conversion to `const T&` may
+          // return temp objects, e.g for vector<bool>.
+          if (!mono_tuple_matcher_.MatchAndExplain(
+                  InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),
+                                  ImplicitCast_<const RhsValue&>(*right)),
+                  &inner_listener)) {
+            *listener << "where the value pair (";
+            UniversalPrint(*left, listener->stream());
+            *listener << ", ";
+            UniversalPrint(*right, listener->stream());
+            *listener << ") at index #" << i << " don't match";
+            PrintIfNotEmpty(inner_listener.str(), listener->stream());
+            return false;
+          }
+        } else {
+          if (!mono_tuple_matcher_.Matches(
+                  InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),
+                                  ImplicitCast_<const RhsValue&>(*right))))
+            return false;
+        }
+      }
+
+      return true;
+    }
+
+   private:
+    const Matcher<InnerMatcherArg> mono_tuple_matcher_;
+    const RhsStlContainer rhs_;
+
+    GTEST_DISALLOW_ASSIGN_(Impl);
+  };
+
+ private:
+  const TupleMatcher tuple_matcher_;
+  const RhsStlContainer rhs_;
+
+  GTEST_DISALLOW_ASSIGN_(PointwiseMatcher);
+};
+
+// Holds the logic common to ContainsMatcherImpl and EachMatcherImpl.
+template <typename Container>
+class QuantifierMatcherImpl : public MatcherInterface<Container> {
+ public:
+  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
+  typedef StlContainerView<RawContainer> View;
+  typedef typename View::type StlContainer;
+  typedef typename View::const_reference StlContainerReference;
+  typedef typename StlContainer::value_type Element;
+
+  template <typename InnerMatcher>
+  explicit QuantifierMatcherImpl(InnerMatcher inner_matcher)
+      : inner_matcher_(
+           testing::SafeMatcherCast<const Element&>(inner_matcher)) {}
+
+  // Checks whether:
+  // * All elements in the container match, if all_elements_should_match.
+  // * Any element in the container matches, if !all_elements_should_match.
+  bool MatchAndExplainImpl(bool all_elements_should_match,
+                           Container container,
+                           MatchResultListener* listener) const {
+    StlContainerReference stl_container = View::ConstReference(container);
+    size_t i = 0;
+    for (typename StlContainer::const_iterator it = stl_container.begin();
+         it != stl_container.end(); ++it, ++i) {
+      StringMatchResultListener inner_listener;
+      const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);
+
+      if (matches != all_elements_should_match) {
+        *listener << "whose element #" << i
+                  << (matches ? " matches" : " doesn't match");
+        PrintIfNotEmpty(inner_listener.str(), listener->stream());
+        return !all_elements_should_match;
+      }
+    }
+    return all_elements_should_match;
+  }
+
+ protected:
+  const Matcher<const Element&> inner_matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(QuantifierMatcherImpl);
+};
+
+// Implements Contains(element_matcher) for the given argument type Container.
+// Symmetric to EachMatcherImpl.
+template <typename Container>
+class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> {
+ public:
+  template <typename InnerMatcher>
+  explicit ContainsMatcherImpl(InnerMatcher inner_matcher)
+      : QuantifierMatcherImpl<Container>(inner_matcher) {}
+
+  // Describes what this matcher does.
+  void DescribeTo(::std::ostream* os) const override {
+    *os << "contains at least one element that ";
+    this->inner_matcher_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const override {
+    *os << "doesn't contain any element that ";
+    this->inner_matcher_.DescribeTo(os);
+  }
+
+  bool MatchAndExplain(Container container,
+                       MatchResultListener* listener) const override {
+    return this->MatchAndExplainImpl(false, container, listener);
+  }
+
+ private:
+  GTEST_DISALLOW_ASSIGN_(ContainsMatcherImpl);
+};
+
+// Implements Each(element_matcher) for the given argument type Container.
+// Symmetric to ContainsMatcherImpl.
+template <typename Container>
+class EachMatcherImpl : public QuantifierMatcherImpl<Container> {
+ public:
+  template <typename InnerMatcher>
+  explicit EachMatcherImpl(InnerMatcher inner_matcher)
+      : QuantifierMatcherImpl<Container>(inner_matcher) {}
+
+  // Describes what this matcher does.
+  void DescribeTo(::std::ostream* os) const override {
+    *os << "only contains elements that ";
+    this->inner_matcher_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const override {
+    *os << "contains some element that ";
+    this->inner_matcher_.DescribeNegationTo(os);
+  }
+
+  bool MatchAndExplain(Container container,
+                       MatchResultListener* listener) const override {
+    return this->MatchAndExplainImpl(true, container, listener);
+  }
+
+ private:
+  GTEST_DISALLOW_ASSIGN_(EachMatcherImpl);
+};
+
+// Implements polymorphic Contains(element_matcher).
+template <typename M>
+class ContainsMatcher {
+ public:
+  explicit ContainsMatcher(M m) : inner_matcher_(m) {}
+
+  template <typename Container>
+  operator Matcher<Container>() const {
+    return Matcher<Container>(
+        new ContainsMatcherImpl<const Container&>(inner_matcher_));
+  }
+
+ private:
+  const M inner_matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(ContainsMatcher);
+};
+
+// Implements polymorphic Each(element_matcher).
+template <typename M>
+class EachMatcher {
+ public:
+  explicit EachMatcher(M m) : inner_matcher_(m) {}
+
+  template <typename Container>
+  operator Matcher<Container>() const {
+    return Matcher<Container>(
+        new EachMatcherImpl<const Container&>(inner_matcher_));
+  }
+
+ private:
+  const M inner_matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(EachMatcher);
+};
+
+struct Rank1 {};
+struct Rank0 : Rank1 {};
+
+namespace pair_getters {
+using std::get;
+template <typename T>
+auto First(T& x, Rank1) -> decltype(get<0>(x)) {  // NOLINT
+  return get<0>(x);
+}
+template <typename T>
+auto First(T& x, Rank0) -> decltype((x.first)) {  // NOLINT
+  return x.first;
+}
+
+template <typename T>
+auto Second(T& x, Rank1) -> decltype(get<1>(x)) {  // NOLINT
+  return get<1>(x);
+}
+template <typename T>
+auto Second(T& x, Rank0) -> decltype((x.second)) {  // NOLINT
+  return x.second;
+}
+}  // namespace pair_getters
+
+// Implements Key(inner_matcher) for the given argument pair type.
+// Key(inner_matcher) matches an std::pair whose 'first' field matches
+// inner_matcher.  For example, Contains(Key(Ge(5))) can be used to match an
+// std::map that contains at least one element whose key is >= 5.
+template <typename PairType>
+class KeyMatcherImpl : public MatcherInterface<PairType> {
+ public:
+  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType;
+  typedef typename RawPairType::first_type KeyType;
+
+  template <typename InnerMatcher>
+  explicit KeyMatcherImpl(InnerMatcher inner_matcher)
+      : inner_matcher_(
+          testing::SafeMatcherCast<const KeyType&>(inner_matcher)) {
+  }
+
+  // Returns true iff 'key_value.first' (the key) matches the inner matcher.
+  bool MatchAndExplain(PairType key_value,
+                       MatchResultListener* listener) const override {
+    StringMatchResultListener inner_listener;
+    const bool match = inner_matcher_.MatchAndExplain(
+        pair_getters::First(key_value, Rank0()), &inner_listener);
+    const std::string explanation = inner_listener.str();
+    if (explanation != "") {
+      *listener << "whose first field is a value " << explanation;
+    }
+    return match;
+  }
+
+  // Describes what this matcher does.
+  void DescribeTo(::std::ostream* os) const override {
+    *os << "has a key that ";
+    inner_matcher_.DescribeTo(os);
+  }
+
+  // Describes what the negation of this matcher does.
+  void DescribeNegationTo(::std::ostream* os) const override {
+    *os << "doesn't have a key that ";
+    inner_matcher_.DescribeTo(os);
+  }
+
+ private:
+  const Matcher<const KeyType&> inner_matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(KeyMatcherImpl);
+};
+
+// Implements polymorphic Key(matcher_for_key).
+template <typename M>
+class KeyMatcher {
+ public:
+  explicit KeyMatcher(M m) : matcher_for_key_(m) {}
+
+  template <typename PairType>
+  operator Matcher<PairType>() const {
+    return Matcher<PairType>(
+        new KeyMatcherImpl<const PairType&>(matcher_for_key_));
+  }
+
+ private:
+  const M matcher_for_key_;
+
+  GTEST_DISALLOW_ASSIGN_(KeyMatcher);
+};
+
+// Implements Pair(first_matcher, second_matcher) for the given argument pair
+// type with its two matchers. See Pair() function below.
+template <typename PairType>
+class PairMatcherImpl : public MatcherInterface<PairType> {
+ public:
+  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType;
+  typedef typename RawPairType::first_type FirstType;
+  typedef typename RawPairType::second_type SecondType;
+
+  template <typename FirstMatcher, typename SecondMatcher>
+  PairMatcherImpl(FirstMatcher first_matcher, SecondMatcher second_matcher)
+      : first_matcher_(
+            testing::SafeMatcherCast<const FirstType&>(first_matcher)),
+        second_matcher_(
+            testing::SafeMatcherCast<const SecondType&>(second_matcher)) {
+  }
+
+  // Describes what this matcher does.
+  void DescribeTo(::std::ostream* os) const override {
+    *os << "has a first field that ";
+    first_matcher_.DescribeTo(os);
+    *os << ", and has a second field that ";
+    second_matcher_.DescribeTo(os);
+  }
+
+  // Describes what the negation of this matcher does.
+  void DescribeNegationTo(::std::ostream* os) const override {
+    *os << "has a first field that ";
+    first_matcher_.DescribeNegationTo(os);
+    *os << ", or has a second field that ";
+    second_matcher_.DescribeNegationTo(os);
+  }
+
+  // Returns true iff 'a_pair.first' matches first_matcher and 'a_pair.second'
+  // matches second_matcher.
+  bool MatchAndExplain(PairType a_pair,
+                       MatchResultListener* listener) const override {
+    if (!listener->IsInterested()) {
+      // If the listener is not interested, we don't need to construct the
+      // explanation.
+      return first_matcher_.Matches(pair_getters::First(a_pair, Rank0())) &&
+             second_matcher_.Matches(pair_getters::Second(a_pair, Rank0()));
+    }
+    StringMatchResultListener first_inner_listener;
+    if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank0()),
+                                        &first_inner_listener)) {
+      *listener << "whose first field does not match";
+      PrintIfNotEmpty(first_inner_listener.str(), listener->stream());
+      return false;
+    }
+    StringMatchResultListener second_inner_listener;
+    if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank0()),
+                                         &second_inner_listener)) {
+      *listener << "whose second field does not match";
+      PrintIfNotEmpty(second_inner_listener.str(), listener->stream());
+      return false;
+    }
+    ExplainSuccess(first_inner_listener.str(), second_inner_listener.str(),
+                   listener);
+    return true;
+  }
+
+ private:
+  void ExplainSuccess(const std::string& first_explanation,
+                      const std::string& second_explanation,
+                      MatchResultListener* listener) const {
+    *listener << "whose both fields match";
+    if (first_explanation != "") {
+      *listener << ", where the first field is a value " << first_explanation;
+    }
+    if (second_explanation != "") {
+      *listener << ", ";
+      if (first_explanation != "") {
+        *listener << "and ";
+      } else {
+        *listener << "where ";
+      }
+      *listener << "the second field is a value " << second_explanation;
+    }
+  }
+
+  const Matcher<const FirstType&> first_matcher_;
+  const Matcher<const SecondType&> second_matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(PairMatcherImpl);
+};
+
+// Implements polymorphic Pair(first_matcher, second_matcher).
+template <typename FirstMatcher, typename SecondMatcher>
+class PairMatcher {
+ public:
+  PairMatcher(FirstMatcher first_matcher, SecondMatcher second_matcher)
+      : first_matcher_(first_matcher), second_matcher_(second_matcher) {}
+
+  template <typename PairType>
+  operator Matcher<PairType> () const {
+    return Matcher<PairType>(
+        new PairMatcherImpl<const PairType&>(first_matcher_, second_matcher_));
+  }
+
+ private:
+  const FirstMatcher first_matcher_;
+  const SecondMatcher second_matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(PairMatcher);
+};
+
+// Implements ElementsAre() and ElementsAreArray().
+template <typename Container>
+class ElementsAreMatcherImpl : public MatcherInterface<Container> {
+ public:
+  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
+  typedef internal::StlContainerView<RawContainer> View;
+  typedef typename View::type StlContainer;
+  typedef typename View::const_reference StlContainerReference;
+  typedef typename StlContainer::value_type Element;
+
+  // Constructs the matcher from a sequence of element values or
+  // element matchers.
+  template <typename InputIter>
+  ElementsAreMatcherImpl(InputIter first, InputIter last) {
+    while (first != last) {
+      matchers_.push_back(MatcherCast<const Element&>(*first++));
+    }
+  }
+
+  // Describes what this matcher does.
+  void DescribeTo(::std::ostream* os) const override {
+    if (count() == 0) {
+      *os << "is empty";
+    } else if (count() == 1) {
+      *os << "has 1 element that ";
+      matchers_[0].DescribeTo(os);
+    } else {
+      *os << "has " << Elements(count()) << " where\n";
+      for (size_t i = 0; i != count(); ++i) {
+        *os << "element #" << i << " ";
+        matchers_[i].DescribeTo(os);
+        if (i + 1 < count()) {
+          *os << ",\n";
+        }
+      }
+    }
+  }
+
+  // Describes what the negation of this matcher does.
+  void DescribeNegationTo(::std::ostream* os) const override {
+    if (count() == 0) {
+      *os << "isn't empty";
+      return;
+    }
+
+    *os << "doesn't have " << Elements(count()) << ", or\n";
+    for (size_t i = 0; i != count(); ++i) {
+      *os << "element #" << i << " ";
+      matchers_[i].DescribeNegationTo(os);
+      if (i + 1 < count()) {
+        *os << ", or\n";
+      }
+    }
+  }
+
+  bool MatchAndExplain(Container container,
+                       MatchResultListener* listener) const override {
+    // To work with stream-like "containers", we must only walk
+    // through the elements in one pass.
+
+    const bool listener_interested = listener->IsInterested();
+
+    // explanations[i] is the explanation of the element at index i.
+    ::std::vector<std::string> explanations(count());
+    StlContainerReference stl_container = View::ConstReference(container);
+    typename StlContainer::const_iterator it = stl_container.begin();
+    size_t exam_pos = 0;
+    bool mismatch_found = false;  // Have we found a mismatched element yet?
+
+    // Go through the elements and matchers in pairs, until we reach
+    // the end of either the elements or the matchers, or until we find a
+    // mismatch.
+    for (; it != stl_container.end() && exam_pos != count(); ++it, ++exam_pos) {
+      bool match;  // Does the current element match the current matcher?
+      if (listener_interested) {
+        StringMatchResultListener s;
+        match = matchers_[exam_pos].MatchAndExplain(*it, &s);
+        explanations[exam_pos] = s.str();
+      } else {
+        match = matchers_[exam_pos].Matches(*it);
+      }
+
+      if (!match) {
+        mismatch_found = true;
+        break;
+      }
+    }
+    // If mismatch_found is true, 'exam_pos' is the index of the mismatch.
+
+    // Find how many elements the actual container has.  We avoid
+    // calling size() s.t. this code works for stream-like "containers"
+    // that don't define size().
+    size_t actual_count = exam_pos;
+    for (; it != stl_container.end(); ++it) {
+      ++actual_count;
+    }
+
+    if (actual_count != count()) {
+      // The element count doesn't match.  If the container is empty,
+      // there's no need to explain anything as Google Mock already
+      // prints the empty container.  Otherwise we just need to show
+      // how many elements there actually are.
+      if (listener_interested && (actual_count != 0)) {
+        *listener << "which has " << Elements(actual_count);
+      }
+      return false;
+    }
+
+    if (mismatch_found) {
+      // The element count matches, but the exam_pos-th element doesn't match.
+      if (listener_interested) {
+        *listener << "whose element #" << exam_pos << " doesn't match";
+        PrintIfNotEmpty(explanations[exam_pos], listener->stream());
+      }
+      return false;
+    }
+
+    // Every element matches its expectation.  We need to explain why
+    // (the obvious ones can be skipped).
+    if (listener_interested) {
+      bool reason_printed = false;
+      for (size_t i = 0; i != count(); ++i) {
+        const std::string& s = explanations[i];
+        if (!s.empty()) {
+          if (reason_printed) {
+            *listener << ",\nand ";
+          }
+          *listener << "whose element #" << i << " matches, " << s;
+          reason_printed = true;
+        }
+      }
+    }
+    return true;
+  }
+
+ private:
+  static Message Elements(size_t count) {
+    return Message() << count << (count == 1 ? " element" : " elements");
+  }
+
+  size_t count() const { return matchers_.size(); }
+
+  ::std::vector<Matcher<const Element&> > matchers_;
+
+  GTEST_DISALLOW_ASSIGN_(ElementsAreMatcherImpl);
+};
+
+// Connectivity matrix of (elements X matchers), in element-major order.
+// Initially, there are no edges.
+// Use NextGraph() to iterate over all possible edge configurations.
+// Use Randomize() to generate a random edge configuration.
+class GTEST_API_ MatchMatrix {
+ public:
+  MatchMatrix(size_t num_elements, size_t num_matchers)
+      : num_elements_(num_elements),
+        num_matchers_(num_matchers),
+        matched_(num_elements_* num_matchers_, 0) {
+  }
+
+  size_t LhsSize() const { return num_elements_; }
+  size_t RhsSize() const { return num_matchers_; }
+  bool HasEdge(size_t ilhs, size_t irhs) const {
+    return matched_[SpaceIndex(ilhs, irhs)] == 1;
+  }
+  void SetEdge(size_t ilhs, size_t irhs, bool b) {
+    matched_[SpaceIndex(ilhs, irhs)] = b ? 1 : 0;
+  }
+
+  // Treating the connectivity matrix as a (LhsSize()*RhsSize())-bit number,
+  // adds 1 to that number; returns false if incrementing the graph left it
+  // empty.
+  bool NextGraph();
+
+  void Randomize();
+
+  std::string DebugString() const;
+
+ private:
+  size_t SpaceIndex(size_t ilhs, size_t irhs) const {
+    return ilhs * num_matchers_ + irhs;
+  }
+
+  size_t num_elements_;
+  size_t num_matchers_;
+
+  // Each element is a char interpreted as bool. They are stored as a
+  // flattened array in lhs-major order, use 'SpaceIndex()' to translate
+  // a (ilhs, irhs) matrix coordinate into an offset.
+  ::std::vector<char> matched_;
+};
+
+typedef ::std::pair<size_t, size_t> ElementMatcherPair;
+typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs;
+
+// Returns a maximum bipartite matching for the specified graph 'g'.
+// The matching is represented as a vector of {element, matcher} pairs.
+GTEST_API_ ElementMatcherPairs
+FindMaxBipartiteMatching(const MatchMatrix& g);
+
+struct UnorderedMatcherRequire {
+  enum Flags {
+    Superset = 1 << 0,
+    Subset = 1 << 1,
+    ExactMatch = Superset | Subset,
+  };
+};
+
+// Untyped base class for implementing UnorderedElementsAre.  By
+// putting logic that's not specific to the element type here, we
+// reduce binary bloat and increase compilation speed.
+class GTEST_API_ UnorderedElementsAreMatcherImplBase {
+ protected:
+  explicit UnorderedElementsAreMatcherImplBase(
+      UnorderedMatcherRequire::Flags matcher_flags)
+      : match_flags_(matcher_flags) {}
+
+  // A vector of matcher describers, one for each element matcher.
+  // Does not own the describers (and thus can be used only when the
+  // element matchers are alive).
+  typedef ::std::vector<const MatcherDescriberInterface*> MatcherDescriberVec;
+
+  // Describes this UnorderedElementsAre matcher.
+  void DescribeToImpl(::std::ostream* os) const;
+
+  // Describes the negation of this UnorderedElementsAre matcher.
+  void DescribeNegationToImpl(::std::ostream* os) const;
+
+  bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts,
+                         const MatchMatrix& matrix,
+                         MatchResultListener* listener) const;
+
+  bool FindPairing(const MatchMatrix& matrix,
+                   MatchResultListener* listener) const;
+
+  MatcherDescriberVec& matcher_describers() {
+    return matcher_describers_;
+  }
+
+  static Message Elements(size_t n) {
+    return Message() << n << " element" << (n == 1 ? "" : "s");
+  }
+
+  UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; }
+
+ private:
+  UnorderedMatcherRequire::Flags match_flags_;
+  MatcherDescriberVec matcher_describers_;
+
+  GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase);
+};
+
+// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and
+// IsSupersetOf.
+template <typename Container>
+class UnorderedElementsAreMatcherImpl
+    : public MatcherInterface<Container>,
+      public UnorderedElementsAreMatcherImplBase {
+ public:
+  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
+  typedef internal::StlContainerView<RawContainer> View;
+  typedef typename View::type StlContainer;
+  typedef typename View::const_reference StlContainerReference;
+  typedef typename StlContainer::const_iterator StlContainerConstIterator;
+  typedef typename StlContainer::value_type Element;
+
+  template <typename InputIter>
+  UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,
+                                  InputIter first, InputIter last)
+      : UnorderedElementsAreMatcherImplBase(matcher_flags) {
+    for (; first != last; ++first) {
+      matchers_.push_back(MatcherCast<const Element&>(*first));
+      matcher_describers().push_back(matchers_.back().GetDescriber());
+    }
+  }
+
+  // Describes what this matcher does.
+  void DescribeTo(::std::ostream* os) const override {
+    return UnorderedElementsAreMatcherImplBase::DescribeToImpl(os);
+  }
+
+  // Describes what the negation of this matcher does.
+  void DescribeNegationTo(::std::ostream* os) const override {
+    return UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(os);
+  }
+
+  bool MatchAndExplain(Container container,
+                       MatchResultListener* listener) const override {
+    StlContainerReference stl_container = View::ConstReference(container);
+    ::std::vector<std::string> element_printouts;
+    MatchMatrix matrix =
+        AnalyzeElements(stl_container.begin(), stl_container.end(),
+                        &element_printouts, listener);
+
+    if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {
+      return true;
+    }
+
+    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+      if (matrix.LhsSize() != matrix.RhsSize()) {
+        // The element count doesn't match.  If the container is empty,
+        // there's no need to explain anything as Google Mock already
+        // prints the empty container. Otherwise we just need to show
+        // how many elements there actually are.
+        if (matrix.LhsSize() != 0 && listener->IsInterested()) {
+          *listener << "which has " << Elements(matrix.LhsSize());
+        }
+        return false;
+      }
+    }
+
+    return VerifyMatchMatrix(element_printouts, matrix, listener) &&
+           FindPairing(matrix, listener);
+  }
+
+ private:
+  template <typename ElementIter>
+  MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
+                              ::std::vector<std::string>* element_printouts,
+                              MatchResultListener* listener) const {
+    element_printouts->clear();
+    ::std::vector<char> did_match;
+    size_t num_elements = 0;
+    for (; elem_first != elem_last; ++num_elements, ++elem_first) {
+      if (listener->IsInterested()) {
+        element_printouts->push_back(PrintToString(*elem_first));
+      }
+      for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) {
+        did_match.push_back(Matches(matchers_[irhs])(*elem_first));
+      }
+    }
+
+    MatchMatrix matrix(num_elements, matchers_.size());
+    ::std::vector<char>::const_iterator did_match_iter = did_match.begin();
+    for (size_t ilhs = 0; ilhs != num_elements; ++ilhs) {
+      for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) {
+        matrix.SetEdge(ilhs, irhs, *did_match_iter++ != 0);
+      }
+    }
+    return matrix;
+  }
+
+  ::std::vector<Matcher<const Element&> > matchers_;
+
+  GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl);
+};
+
+// Functor for use in TransformTuple.
+// Performs MatcherCast<Target> on an input argument of any type.
+template <typename Target>
+struct CastAndAppendTransform {
+  template <typename Arg>
+  Matcher<Target> operator()(const Arg& a) const {
+    return MatcherCast<Target>(a);
+  }
+};
+
+// Implements UnorderedElementsAre.
+template <typename MatcherTuple>
+class UnorderedElementsAreMatcher {
+ public:
+  explicit UnorderedElementsAreMatcher(const MatcherTuple& args)
+      : matchers_(args) {}
+
+  template <typename Container>
+  operator Matcher<Container>() const {
+    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
+    typedef typename internal::StlContainerView<RawContainer>::type View;
+    typedef typename View::value_type Element;
+    typedef ::std::vector<Matcher<const Element&> > MatcherVec;
+    MatcherVec matchers;
+    matchers.reserve(::std::tuple_size<MatcherTuple>::value);
+    TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
+                         ::std::back_inserter(matchers));
+    return Matcher<Container>(
+        new UnorderedElementsAreMatcherImpl<const Container&>(
+            UnorderedMatcherRequire::ExactMatch, matchers.begin(),
+            matchers.end()));
+  }
+
+ private:
+  const MatcherTuple matchers_;
+  GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcher);
+};
+
+// Implements ElementsAre.
+template <typename MatcherTuple>
+class ElementsAreMatcher {
+ public:
+  explicit ElementsAreMatcher(const MatcherTuple& args) : matchers_(args) {}
+
+  template <typename Container>
+  operator Matcher<Container>() const {
+    GTEST_COMPILE_ASSERT_(
+        !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value ||
+            ::std::tuple_size<MatcherTuple>::value < 2,
+        use_UnorderedElementsAre_with_hash_tables);
+
+    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
+    typedef typename internal::StlContainerView<RawContainer>::type View;
+    typedef typename View::value_type Element;
+    typedef ::std::vector<Matcher<const Element&> > MatcherVec;
+    MatcherVec matchers;
+    matchers.reserve(::std::tuple_size<MatcherTuple>::value);
+    TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
+                         ::std::back_inserter(matchers));
+    return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(
+        matchers.begin(), matchers.end()));
+  }
+
+ private:
+  const MatcherTuple matchers_;
+  GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher);
+};
+
+// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf().
+template <typename T>
+class UnorderedElementsAreArrayMatcher {
+ public:
+  template <typename Iter>
+  UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags,
+                                   Iter first, Iter last)
+      : match_flags_(match_flags), matchers_(first, last) {}
+
+  template <typename Container>
+  operator Matcher<Container>() const {
+    return Matcher<Container>(
+        new UnorderedElementsAreMatcherImpl<const Container&>(
+            match_flags_, matchers_.begin(), matchers_.end()));
+  }
+
+ private:
+  UnorderedMatcherRequire::Flags match_flags_;
+  ::std::vector<T> matchers_;
+
+  GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher);
+};
+
+// Implements ElementsAreArray().
+template <typename T>
+class ElementsAreArrayMatcher {
+ public:
+  template <typename Iter>
+  ElementsAreArrayMatcher(Iter first, Iter last) : matchers_(first, last) {}
+
+  template <typename Container>
+  operator Matcher<Container>() const {
+    GTEST_COMPILE_ASSERT_(
+        !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value,
+        use_UnorderedElementsAreArray_with_hash_tables);
+
+    return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(
+        matchers_.begin(), matchers_.end()));
+  }
+
+ private:
+  const ::std::vector<T> matchers_;
+
+  GTEST_DISALLOW_ASSIGN_(ElementsAreArrayMatcher);
+};
+
+// Given a 2-tuple matcher tm of type Tuple2Matcher and a value second
+// of type Second, BoundSecondMatcher<Tuple2Matcher, Second>(tm,
+// second) is a polymorphic matcher that matches a value x iff tm
+// matches tuple (x, second).  Useful for implementing
+// UnorderedPointwise() in terms of UnorderedElementsAreArray().
+//
+// BoundSecondMatcher is copyable and assignable, as we need to put
+// instances of this class in a vector when implementing
+// UnorderedPointwise().
+template <typename Tuple2Matcher, typename Second>
+class BoundSecondMatcher {
+ public:
+  BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second)
+      : tuple2_matcher_(tm), second_value_(second) {}
+
+  template <typename T>
+  operator Matcher<T>() const {
+    return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_));
+  }
+
+  // We have to define this for UnorderedPointwise() to compile in
+  // C++98 mode, as it puts BoundSecondMatcher instances in a vector,
+  // which requires the elements to be assignable in C++98.  The
+  // compiler cannot generate the operator= for us, as Tuple2Matcher
+  // and Second may not be assignable.
+  //
+  // However, this should never be called, so the implementation just
+  // need to assert.
+  void operator=(const BoundSecondMatcher& /*rhs*/) {
+    GTEST_LOG_(FATAL) << "BoundSecondMatcher should never be assigned.";
+  }
+
+ private:
+  template <typename T>
+  class Impl : public MatcherInterface<T> {
+   public:
+    typedef ::std::tuple<T, Second> ArgTuple;
+
+    Impl(const Tuple2Matcher& tm, const Second& second)
+        : mono_tuple2_matcher_(SafeMatcherCast<const ArgTuple&>(tm)),
+          second_value_(second) {}
+
+    void DescribeTo(::std::ostream* os) const override {
+      *os << "and ";
+      UniversalPrint(second_value_, os);
+      *os << " ";
+      mono_tuple2_matcher_.DescribeTo(os);
+    }
+
+    bool MatchAndExplain(T x, MatchResultListener* listener) const override {
+      return mono_tuple2_matcher_.MatchAndExplain(ArgTuple(x, second_value_),
+                                                  listener);
+    }
+
+   private:
+    const Matcher<const ArgTuple&> mono_tuple2_matcher_;
+    const Second second_value_;
+
+    GTEST_DISALLOW_ASSIGN_(Impl);
+  };
+
+  const Tuple2Matcher tuple2_matcher_;
+  const Second second_value_;
+};
+
+// Given a 2-tuple matcher tm and a value second,
+// MatcherBindSecond(tm, second) returns a matcher that matches a
+// value x iff tm matches tuple (x, second).  Useful for implementing
+// UnorderedPointwise() in terms of UnorderedElementsAreArray().
+template <typename Tuple2Matcher, typename Second>
+BoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond(
+    const Tuple2Matcher& tm, const Second& second) {
+  return BoundSecondMatcher<Tuple2Matcher, Second>(tm, second);
+}
+
+// Returns the description for a matcher defined using the MATCHER*()
+// macro where the user-supplied description string is "", if
+// 'negation' is false; otherwise returns the description of the
+// negation of the matcher.  'param_values' contains a list of strings
+// that are the print-out of the matcher's parameters.
+GTEST_API_ std::string FormatMatcherDescription(bool negation,
+                                                const char* matcher_name,
+                                                const Strings& param_values);
+
+// Implements a matcher that checks the value of a optional<> type variable.
+template <typename ValueMatcher>
+class OptionalMatcher {
+ public:
+  explicit OptionalMatcher(const ValueMatcher& value_matcher)
+      : value_matcher_(value_matcher) {}
+
+  template <typename Optional>
+  operator Matcher<Optional>() const {
+    return Matcher<Optional>(new Impl<const Optional&>(value_matcher_));
+  }
+
+  template <typename Optional>
+  class Impl : public MatcherInterface<Optional> {
+   public:
+    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Optional) OptionalView;
+    typedef typename OptionalView::value_type ValueType;
+    explicit Impl(const ValueMatcher& value_matcher)
+        : value_matcher_(MatcherCast<ValueType>(value_matcher)) {}
+
+    void DescribeTo(::std::ostream* os) const override {
+      *os << "value ";
+      value_matcher_.DescribeTo(os);
+    }
+
+    void DescribeNegationTo(::std::ostream* os) const override {
+      *os << "value ";
+      value_matcher_.DescribeNegationTo(os);
+    }
+
+    bool MatchAndExplain(Optional optional,
+                         MatchResultListener* listener) const override {
+      if (!optional) {
+        *listener << "which is not engaged";
+        return false;
+      }
+      const ValueType& value = *optional;
+      StringMatchResultListener value_listener;
+      const bool match = value_matcher_.MatchAndExplain(value, &value_listener);
+      *listener << "whose value " << PrintToString(value)
+                << (match ? " matches" : " doesn't match");
+      PrintIfNotEmpty(value_listener.str(), listener->stream());
+      return match;
+    }
+
+   private:
+    const Matcher<ValueType> value_matcher_;
+    GTEST_DISALLOW_ASSIGN_(Impl);
+  };
+
+ private:
+  const ValueMatcher value_matcher_;
+  GTEST_DISALLOW_ASSIGN_(OptionalMatcher);
+};
+
+namespace variant_matcher {
+// Overloads to allow VariantMatcher to do proper ADL lookup.
+template <typename T>
+void holds_alternative() {}
+template <typename T>
+void get() {}
+
+// Implements a matcher that checks the value of a variant<> type variable.
+template <typename T>
+class VariantMatcher {
+ public:
+  explicit VariantMatcher(::testing::Matcher<const T&> matcher)
+      : matcher_(std::move(matcher)) {}
+
+  template <typename Variant>
+  bool MatchAndExplain(const Variant& value,
+                       ::testing::MatchResultListener* listener) const {
+    using std::get;
+    if (!listener->IsInterested()) {
+      return holds_alternative<T>(value) && matcher_.Matches(get<T>(value));
+    }
+
+    if (!holds_alternative<T>(value)) {
+      *listener << "whose value is not of type '" << GetTypeName() << "'";
+      return false;
+    }
+
+    const T& elem = get<T>(value);
+    StringMatchResultListener elem_listener;
+    const bool match = matcher_.MatchAndExplain(elem, &elem_listener);
+    *listener << "whose value " << PrintToString(elem)
+              << (match ? " matches" : " doesn't match");
+    PrintIfNotEmpty(elem_listener.str(), listener->stream());
+    return match;
+  }
+
+  void DescribeTo(std::ostream* os) const {
+    *os << "is a variant<> with value of type '" << GetTypeName()
+        << "' and the value ";
+    matcher_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(std::ostream* os) const {
+    *os << "is a variant<> with value of type other than '" << GetTypeName()
+        << "' or the value ";
+    matcher_.DescribeNegationTo(os);
+  }
+
+ private:
+  static std::string GetTypeName() {
+#if GTEST_HAS_RTTI
+    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(
+        return internal::GetTypeName<T>());
+#endif
+    return "the element type";
+  }
+
+  const ::testing::Matcher<const T&> matcher_;
+};
+
+}  // namespace variant_matcher
+
+namespace any_cast_matcher {
+
+// Overloads to allow AnyCastMatcher to do proper ADL lookup.
+template <typename T>
+void any_cast() {}
+
+// Implements a matcher that any_casts the value.
+template <typename T>
+class AnyCastMatcher {
+ public:
+  explicit AnyCastMatcher(const ::testing::Matcher<const T&>& matcher)
+      : matcher_(matcher) {}
+
+  template <typename AnyType>
+  bool MatchAndExplain(const AnyType& value,
+                       ::testing::MatchResultListener* listener) const {
+    if (!listener->IsInterested()) {
+      const T* ptr = any_cast<T>(&value);
+      return ptr != nullptr && matcher_.Matches(*ptr);
+    }
+
+    const T* elem = any_cast<T>(&value);
+    if (elem == nullptr) {
+      *listener << "whose value is not of type '" << GetTypeName() << "'";
+      return false;
+    }
+
+    StringMatchResultListener elem_listener;
+    const bool match = matcher_.MatchAndExplain(*elem, &elem_listener);
+    *listener << "whose value " << PrintToString(*elem)
+              << (match ? " matches" : " doesn't match");
+    PrintIfNotEmpty(elem_listener.str(), listener->stream());
+    return match;
+  }
+
+  void DescribeTo(std::ostream* os) const {
+    *os << "is an 'any' type with value of type '" << GetTypeName()
+        << "' and the value ";
+    matcher_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(std::ostream* os) const {
+    *os << "is an 'any' type with value of type other than '" << GetTypeName()
+        << "' or the value ";
+    matcher_.DescribeNegationTo(os);
+  }
+
+ private:
+  static std::string GetTypeName() {
+#if GTEST_HAS_RTTI
+    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(
+        return internal::GetTypeName<T>());
+#endif
+    return "the element type";
+  }
+
+  const ::testing::Matcher<const T&> matcher_;
+};
+
+}  // namespace any_cast_matcher
+
+// Implements the Args() matcher.
+template <class ArgsTuple, size_t... k>
+class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
+ public:
+  using RawArgsTuple = typename std::decay<ArgsTuple>::type;
+  using SelectedArgs =
+      std::tuple<typename std::tuple_element<k, RawArgsTuple>::type...>;
+  using MonomorphicInnerMatcher = Matcher<const SelectedArgs&>;
+
+  template <typename InnerMatcher>
+  explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
+      : inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
+
+  bool MatchAndExplain(ArgsTuple args,
+                       MatchResultListener* listener) const override {
+    // Workaround spurious C4100 on MSVC<=15.7 when k is empty.
+    (void)args;
+    const SelectedArgs& selected_args =
+        std::forward_as_tuple(std::get<k>(args)...);
+    if (!listener->IsInterested()) return inner_matcher_.Matches(selected_args);
+
+    PrintIndices(listener->stream());
+    *listener << "are " << PrintToString(selected_args);
+
+    StringMatchResultListener inner_listener;
+    const bool match =
+        inner_matcher_.MatchAndExplain(selected_args, &inner_listener);
+    PrintIfNotEmpty(inner_listener.str(), listener->stream());
+    return match;
+  }
+
+  void DescribeTo(::std::ostream* os) const override {
+    *os << "are a tuple ";
+    PrintIndices(os);
+    inner_matcher_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const override {
+    *os << "are a tuple ";
+    PrintIndices(os);
+    inner_matcher_.DescribeNegationTo(os);
+  }
+
+ private:
+  // Prints the indices of the selected fields.
+  static void PrintIndices(::std::ostream* os) {
+    *os << "whose fields (";
+    const char* sep = "";
+    // Workaround spurious C4189 on MSVC<=15.7 when k is empty.
+    (void)sep;
+    const char* dummy[] = {"", (*os << sep << "#" << k, sep = ", ")...};
+    (void)dummy;
+    *os << ") ";
+  }
+
+  MonomorphicInnerMatcher inner_matcher_;
+};
+
+template <class InnerMatcher, size_t... k>
+class ArgsMatcher {
+ public:
+  explicit ArgsMatcher(InnerMatcher inner_matcher)
+      : inner_matcher_(std::move(inner_matcher)) {}
+
+  template <typename ArgsTuple>
+  operator Matcher<ArgsTuple>() const {  // NOLINT
+    return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, k...>(inner_matcher_));
+  }
+
+ private:
+  InnerMatcher inner_matcher_;
+};
+
+}  // namespace internal
+
+// ElementsAreArray(iterator_first, iterator_last)
+// ElementsAreArray(pointer, count)
+// ElementsAreArray(array)
+// ElementsAreArray(container)
+// ElementsAreArray({ e1, e2, ..., en })
+//
+// The ElementsAreArray() functions are like ElementsAre(...), except
+// that they are given a homogeneous sequence rather than taking each
+// element as a function argument. The sequence can be specified as an
+// array, a pointer and count, a vector, an initializer list, or an
+// STL iterator range. In each of these cases, the underlying sequence
+// can be either a sequence of values or a sequence of matchers.
+//
+// All forms of ElementsAreArray() make a copy of the input matcher sequence.
+
+template <typename Iter>
+inline internal::ElementsAreArrayMatcher<
+    typename ::std::iterator_traits<Iter>::value_type>
+ElementsAreArray(Iter first, Iter last) {
+  typedef typename ::std::iterator_traits<Iter>::value_type T;
+  return internal::ElementsAreArrayMatcher<T>(first, last);
+}
+
+template <typename T>
+inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
+    const T* pointer, size_t count) {
+  return ElementsAreArray(pointer, pointer + count);
+}
+
+template <typename T, size_t N>
+inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
+    const T (&array)[N]) {
+  return ElementsAreArray(array, N);
+}
+
+template <typename Container>
+inline internal::ElementsAreArrayMatcher<typename Container::value_type>
+ElementsAreArray(const Container& container) {
+  return ElementsAreArray(container.begin(), container.end());
+}
+
+template <typename T>
+inline internal::ElementsAreArrayMatcher<T>
+ElementsAreArray(::std::initializer_list<T> xs) {
+  return ElementsAreArray(xs.begin(), xs.end());
+}
+
+// UnorderedElementsAreArray(iterator_first, iterator_last)
+// UnorderedElementsAreArray(pointer, count)
+// UnorderedElementsAreArray(array)
+// UnorderedElementsAreArray(container)
+// UnorderedElementsAreArray({ e1, e2, ..., en })
+//
+// UnorderedElementsAreArray() verifies that a bijective mapping onto a
+// collection of matchers exists.
+//
+// The matchers can be specified as an array, a pointer and count, a container,
+// an initializer list, or an STL iterator range. In each of these cases, the
+// underlying matchers can be either values or matchers.
+
+template <typename Iter>
+inline internal::UnorderedElementsAreArrayMatcher<
+    typename ::std::iterator_traits<Iter>::value_type>
+UnorderedElementsAreArray(Iter first, Iter last) {
+  typedef typename ::std::iterator_traits<Iter>::value_type T;
+  return internal::UnorderedElementsAreArrayMatcher<T>(
+      internal::UnorderedMatcherRequire::ExactMatch, first, last);
+}
+
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T>
+UnorderedElementsAreArray(const T* pointer, size_t count) {
+  return UnorderedElementsAreArray(pointer, pointer + count);
+}
+
+template <typename T, size_t N>
+inline internal::UnorderedElementsAreArrayMatcher<T>
+UnorderedElementsAreArray(const T (&array)[N]) {
+  return UnorderedElementsAreArray(array, N);
+}
+
+template <typename Container>
+inline internal::UnorderedElementsAreArrayMatcher<
+    typename Container::value_type>
+UnorderedElementsAreArray(const Container& container) {
+  return UnorderedElementsAreArray(container.begin(), container.end());
+}
+
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T>
+UnorderedElementsAreArray(::std::initializer_list<T> xs) {
+  return UnorderedElementsAreArray(xs.begin(), xs.end());
+}
+
+// _ is a matcher that matches anything of any type.
+//
+// This definition is fine as:
+//
+//   1. The C++ standard permits using the name _ in a namespace that
+//      is not the global namespace or ::std.
+//   2. The AnythingMatcher class has no data member or constructor,
+//      so it's OK to create global variables of this type.
+//   3. c-style has approved of using _ in this case.
+const internal::AnythingMatcher _ = {};
+// Creates a matcher that matches any value of the given type T.
+template <typename T>
+inline Matcher<T> A() {
+  return Matcher<T>(new internal::AnyMatcherImpl<T>());
+}
+
+// Creates a matcher that matches any value of the given type T.
+template <typename T>
+inline Matcher<T> An() { return A<T>(); }
+
+template <typename T, typename M>
+Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl(
+    const M& value,
+    internal::BooleanConstant<false> /* convertible_to_matcher */,
+    internal::BooleanConstant<false> /* convertible_to_T */) {
+  return Eq(value);
+}
+
+// Creates a polymorphic matcher that matches any NULL pointer.
+inline PolymorphicMatcher<internal::IsNullMatcher > IsNull() {
+  return MakePolymorphicMatcher(internal::IsNullMatcher());
+}
+
+// Creates a polymorphic matcher that matches any non-NULL pointer.
+// This is convenient as Not(NULL) doesn't compile (the compiler
+// thinks that that expression is comparing a pointer with an integer).
+inline PolymorphicMatcher<internal::NotNullMatcher > NotNull() {
+  return MakePolymorphicMatcher(internal::NotNullMatcher());
+}
+
+// Creates a polymorphic matcher that matches any argument that
+// references variable x.
+template <typename T>
+inline internal::RefMatcher<T&> Ref(T& x) {  // NOLINT
+  return internal::RefMatcher<T&>(x);
+}
+
+// Creates a matcher that matches any double argument approximately
+// equal to rhs, where two NANs are considered unequal.
+inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) {
+  return internal::FloatingEqMatcher<double>(rhs, false);
+}
+
+// Creates a matcher that matches any double argument approximately
+// equal to rhs, including NaN values when rhs is NaN.
+inline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) {
+  return internal::FloatingEqMatcher<double>(rhs, true);
+}
+
+// Creates a matcher that matches any double argument approximately equal to
+// rhs, up to the specified max absolute error bound, where two NANs are
+// considered unequal.  The max absolute error bound must be non-negative.
+inline internal::FloatingEqMatcher<double> DoubleNear(
+    double rhs, double max_abs_error) {
+  return internal::FloatingEqMatcher<double>(rhs, false, max_abs_error);
+}
+
+// Creates a matcher that matches any double argument approximately equal to
+// rhs, up to the specified max absolute error bound, including NaN values when
+// rhs is NaN.  The max absolute error bound must be non-negative.
+inline internal::FloatingEqMatcher<double> NanSensitiveDoubleNear(
+    double rhs, double max_abs_error) {
+  return internal::FloatingEqMatcher<double>(rhs, true, max_abs_error);
+}
+
+// Creates a matcher that matches any float argument approximately
+// equal to rhs, where two NANs are considered unequal.
+inline internal::FloatingEqMatcher<float> FloatEq(float rhs) {
+  return internal::FloatingEqMatcher<float>(rhs, false);
+}
+
+// Creates a matcher that matches any float argument approximately
+// equal to rhs, including NaN values when rhs is NaN.
+inline internal::FloatingEqMatcher<float> NanSensitiveFloatEq(float rhs) {
+  return internal::FloatingEqMatcher<float>(rhs, true);
+}
+
+// Creates a matcher that matches any float argument approximately equal to
+// rhs, up to the specified max absolute error bound, where two NANs are
+// considered unequal.  The max absolute error bound must be non-negative.
+inline internal::FloatingEqMatcher<float> FloatNear(
+    float rhs, float max_abs_error) {
+  return internal::FloatingEqMatcher<float>(rhs, false, max_abs_error);
+}
+
+// Creates a matcher that matches any float argument approximately equal to
+// rhs, up to the specified max absolute error bound, including NaN values when
+// rhs is NaN.  The max absolute error bound must be non-negative.
+inline internal::FloatingEqMatcher<float> NanSensitiveFloatNear(
+    float rhs, float max_abs_error) {
+  return internal::FloatingEqMatcher<float>(rhs, true, max_abs_error);
+}
+
+// Creates a matcher that matches a pointer (raw or smart) that points
+// to a value that matches inner_matcher.
+template <typename InnerMatcher>
+inline internal::PointeeMatcher<InnerMatcher> Pointee(
+    const InnerMatcher& inner_matcher) {
+  return internal::PointeeMatcher<InnerMatcher>(inner_matcher);
+}
+
+#if GTEST_HAS_RTTI
+// Creates a matcher that matches a pointer or reference that matches
+// inner_matcher when dynamic_cast<To> is applied.
+// The result of dynamic_cast<To> is forwarded to the inner matcher.
+// If To is a pointer and the cast fails, the inner matcher will receive NULL.
+// If To is a reference and the cast fails, this matcher returns false
+// immediately.
+template <typename To>
+inline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To> >
+WhenDynamicCastTo(const Matcher<To>& inner_matcher) {
+  return MakePolymorphicMatcher(
+      internal::WhenDynamicCastToMatcher<To>(inner_matcher));
+}
+#endif  // GTEST_HAS_RTTI
+
+// Creates a matcher that matches an object whose given field matches
+// 'matcher'.  For example,
+//   Field(&Foo::number, Ge(5))
+// matches a Foo object x iff x.number >= 5.
+template <typename Class, typename FieldType, typename FieldMatcher>
+inline PolymorphicMatcher<
+  internal::FieldMatcher<Class, FieldType> > Field(
+    FieldType Class::*field, const FieldMatcher& matcher) {
+  return MakePolymorphicMatcher(
+      internal::FieldMatcher<Class, FieldType>(
+          field, MatcherCast<const FieldType&>(matcher)));
+  // The call to MatcherCast() is required for supporting inner
+  // matchers of compatible types.  For example, it allows
+  //   Field(&Foo::bar, m)
+  // to compile where bar is an int32 and m is a matcher for int64.
+}
+
+// Same as Field() but also takes the name of the field to provide better error
+// messages.
+template <typename Class, typename FieldType, typename FieldMatcher>
+inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType> > Field(
+    const std::string& field_name, FieldType Class::*field,
+    const FieldMatcher& matcher) {
+  return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(
+      field_name, field, MatcherCast<const FieldType&>(matcher)));
+}
+
+// Creates a matcher that matches an object whose given property
+// matches 'matcher'.  For example,
+//   Property(&Foo::str, StartsWith("hi"))
+// matches a Foo object x iff x.str() starts with "hi".
+template <typename Class, typename PropertyType, typename PropertyMatcher>
+inline PolymorphicMatcher<internal::PropertyMatcher<
+    Class, PropertyType, PropertyType (Class::*)() const> >
+Property(PropertyType (Class::*property)() const,
+         const PropertyMatcher& matcher) {
+  return MakePolymorphicMatcher(
+      internal::PropertyMatcher<Class, PropertyType,
+                                PropertyType (Class::*)() const>(
+          property, MatcherCast<const PropertyType&>(matcher)));
+  // The call to MatcherCast() is required for supporting inner
+  // matchers of compatible types.  For example, it allows
+  //   Property(&Foo::bar, m)
+  // to compile where bar() returns an int32 and m is a matcher for int64.
+}
+
+// Same as Property() above, but also takes the name of the property to provide
+// better error messages.
+template <typename Class, typename PropertyType, typename PropertyMatcher>
+inline PolymorphicMatcher<internal::PropertyMatcher<
+    Class, PropertyType, PropertyType (Class::*)() const> >
+Property(const std::string& property_name,
+         PropertyType (Class::*property)() const,
+         const PropertyMatcher& matcher) {
+  return MakePolymorphicMatcher(
+      internal::PropertyMatcher<Class, PropertyType,
+                                PropertyType (Class::*)() const>(
+          property_name, property, MatcherCast<const PropertyType&>(matcher)));
+}
+
+// The same as above but for reference-qualified member functions.
+template <typename Class, typename PropertyType, typename PropertyMatcher>
+inline PolymorphicMatcher<internal::PropertyMatcher<
+    Class, PropertyType, PropertyType (Class::*)() const &> >
+Property(PropertyType (Class::*property)() const &,
+         const PropertyMatcher& matcher) {
+  return MakePolymorphicMatcher(
+      internal::PropertyMatcher<Class, PropertyType,
+                                PropertyType (Class::*)() const&>(
+          property, MatcherCast<const PropertyType&>(matcher)));
+}
+
+// Three-argument form for reference-qualified member functions.
+template <typename Class, typename PropertyType, typename PropertyMatcher>
+inline PolymorphicMatcher<internal::PropertyMatcher<
+    Class, PropertyType, PropertyType (Class::*)() const &> >
+Property(const std::string& property_name,
+         PropertyType (Class::*property)() const &,
+         const PropertyMatcher& matcher) {
+  return MakePolymorphicMatcher(
+      internal::PropertyMatcher<Class, PropertyType,
+                                PropertyType (Class::*)() const&>(
+          property_name, property, MatcherCast<const PropertyType&>(matcher)));
+}
+
+// Creates a matcher that matches an object iff the result of applying
+// a callable to x matches 'matcher'.
+// For example,
+//   ResultOf(f, StartsWith("hi"))
+// matches a Foo object x iff f(x) starts with "hi".
+// `callable` parameter can be a function, function pointer, or a functor. It is
+// required to keep no state affecting the results of the calls on it and make
+// no assumptions about how many calls will be made. Any state it keeps must be
+// protected from the concurrent access.
+template <typename Callable, typename InnerMatcher>
+internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf(
+    Callable callable, InnerMatcher matcher) {
+  return internal::ResultOfMatcher<Callable, InnerMatcher>(
+      std::move(callable), std::move(matcher));
+}
+
+// String matchers.
+
+// Matches a string equal to str.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq(
+    const std::string& str) {
+  return MakePolymorphicMatcher(
+      internal::StrEqualityMatcher<std::string>(str, true, true));
+}
+
+// Matches a string not equal to str.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe(
+    const std::string& str) {
+  return MakePolymorphicMatcher(
+      internal::StrEqualityMatcher<std::string>(str, false, true));
+}
+
+// Matches a string equal to str, ignoring case.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq(
+    const std::string& str) {
+  return MakePolymorphicMatcher(
+      internal::StrEqualityMatcher<std::string>(str, true, false));
+}
+
+// Matches a string not equal to str, ignoring case.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe(
+    const std::string& str) {
+  return MakePolymorphicMatcher(
+      internal::StrEqualityMatcher<std::string>(str, false, false));
+}
+
+// Creates a matcher that matches any string, std::string, or C string
+// that contains the given substring.
+inline PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr(
+    const std::string& substring) {
+  return MakePolymorphicMatcher(
+      internal::HasSubstrMatcher<std::string>(substring));
+}
+
+// Matches a string that starts with 'prefix' (case-sensitive).
+inline PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith(
+    const std::string& prefix) {
+  return MakePolymorphicMatcher(
+      internal::StartsWithMatcher<std::string>(prefix));
+}
+
+// Matches a string that ends with 'suffix' (case-sensitive).
+inline PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith(
+    const std::string& suffix) {
+  return MakePolymorphicMatcher(internal::EndsWithMatcher<std::string>(suffix));
+}
+
+#if GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING
+// Wide string matchers.
+
+// Matches a string equal to str.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrEq(
+    const std::wstring& str) {
+  return MakePolymorphicMatcher(
+      internal::StrEqualityMatcher<std::wstring>(str, true, true));
+}
+
+// Matches a string not equal to str.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrNe(
+    const std::wstring& str) {
+  return MakePolymorphicMatcher(
+      internal::StrEqualityMatcher<std::wstring>(str, false, true));
+}
+
+// Matches a string equal to str, ignoring case.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> >
+StrCaseEq(const std::wstring& str) {
+  return MakePolymorphicMatcher(
+      internal::StrEqualityMatcher<std::wstring>(str, true, false));
+}
+
+// Matches a string not equal to str, ignoring case.
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> >
+StrCaseNe(const std::wstring& str) {
+  return MakePolymorphicMatcher(
+      internal::StrEqualityMatcher<std::wstring>(str, false, false));
+}
+
+// Creates a matcher that matches any ::wstring, std::wstring, or C wide string
+// that contains the given substring.
+inline PolymorphicMatcher<internal::HasSubstrMatcher<std::wstring> > HasSubstr(
+    const std::wstring& substring) {
+  return MakePolymorphicMatcher(
+      internal::HasSubstrMatcher<std::wstring>(substring));
+}
+
+// Matches a string that starts with 'prefix' (case-sensitive).
+inline PolymorphicMatcher<internal::StartsWithMatcher<std::wstring> >
+StartsWith(const std::wstring& prefix) {
+  return MakePolymorphicMatcher(
+      internal::StartsWithMatcher<std::wstring>(prefix));
+}
+
+// Matches a string that ends with 'suffix' (case-sensitive).
+inline PolymorphicMatcher<internal::EndsWithMatcher<std::wstring> > EndsWith(
+    const std::wstring& suffix) {
+  return MakePolymorphicMatcher(
+      internal::EndsWithMatcher<std::wstring>(suffix));
+}
+
+#endif  // GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING
+
+// Creates a polymorphic matcher that matches a 2-tuple where the
+// first field == the second field.
+inline internal::Eq2Matcher Eq() { return internal::Eq2Matcher(); }
+
+// Creates a polymorphic matcher that matches a 2-tuple where the
+// first field >= the second field.
+inline internal::Ge2Matcher Ge() { return internal::Ge2Matcher(); }
+
+// Creates a polymorphic matcher that matches a 2-tuple where the
+// first field > the second field.
+inline internal::Gt2Matcher Gt() { return internal::Gt2Matcher(); }
+
+// Creates a polymorphic matcher that matches a 2-tuple where the
+// first field <= the second field.
+inline internal::Le2Matcher Le() { return internal::Le2Matcher(); }
+
+// Creates a polymorphic matcher that matches a 2-tuple where the
+// first field < the second field.
+inline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); }
+
+// Creates a polymorphic matcher that matches a 2-tuple where the
+// first field != the second field.
+inline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); }
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// FloatEq(first field) matches the second field.
+inline internal::FloatingEq2Matcher<float> FloatEq() {
+  return internal::FloatingEq2Matcher<float>();
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// DoubleEq(first field) matches the second field.
+inline internal::FloatingEq2Matcher<double> DoubleEq() {
+  return internal::FloatingEq2Matcher<double>();
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// FloatEq(first field) matches the second field with NaN equality.
+inline internal::FloatingEq2Matcher<float> NanSensitiveFloatEq() {
+  return internal::FloatingEq2Matcher<float>(true);
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// DoubleEq(first field) matches the second field with NaN equality.
+inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleEq() {
+  return internal::FloatingEq2Matcher<double>(true);
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// FloatNear(first field, max_abs_error) matches the second field.
+inline internal::FloatingEq2Matcher<float> FloatNear(float max_abs_error) {
+  return internal::FloatingEq2Matcher<float>(max_abs_error);
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// DoubleNear(first field, max_abs_error) matches the second field.
+inline internal::FloatingEq2Matcher<double> DoubleNear(double max_abs_error) {
+  return internal::FloatingEq2Matcher<double>(max_abs_error);
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// FloatNear(first field, max_abs_error) matches the second field with NaN
+// equality.
+inline internal::FloatingEq2Matcher<float> NanSensitiveFloatNear(
+    float max_abs_error) {
+  return internal::FloatingEq2Matcher<float>(max_abs_error, true);
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// DoubleNear(first field, max_abs_error) matches the second field with NaN
+// equality.
+inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleNear(
+    double max_abs_error) {
+  return internal::FloatingEq2Matcher<double>(max_abs_error, true);
+}
+
+// Creates a matcher that matches any value of type T that m doesn't
+// match.
+template <typename InnerMatcher>
+inline internal::NotMatcher<InnerMatcher> Not(InnerMatcher m) {
+  return internal::NotMatcher<InnerMatcher>(m);
+}
+
+// Returns a matcher that matches anything that satisfies the given
+// predicate.  The predicate can be any unary function or functor
+// whose return type can be implicitly converted to bool.
+template <typename Predicate>
+inline PolymorphicMatcher<internal::TrulyMatcher<Predicate> >
+Truly(Predicate pred) {
+  return MakePolymorphicMatcher(internal::TrulyMatcher<Predicate>(pred));
+}
+
+// Returns a matcher that matches the container size. The container must
+// support both size() and size_type which all STL-like containers provide.
+// Note that the parameter 'size' can be a value of type size_type as well as
+// matcher. For instance:
+//   EXPECT_THAT(container, SizeIs(2));     // Checks container has 2 elements.
+//   EXPECT_THAT(container, SizeIs(Le(2));  // Checks container has at most 2.
+template <typename SizeMatcher>
+inline internal::SizeIsMatcher<SizeMatcher>
+SizeIs(const SizeMatcher& size_matcher) {
+  return internal::SizeIsMatcher<SizeMatcher>(size_matcher);
+}
+
+// Returns a matcher that matches the distance between the container's begin()
+// iterator and its end() iterator, i.e. the size of the container. This matcher
+// can be used instead of SizeIs with containers such as std::forward_list which
+// do not implement size(). The container must provide const_iterator (with
+// valid iterator_traits), begin() and end().
+template <typename DistanceMatcher>
+inline internal::BeginEndDistanceIsMatcher<DistanceMatcher>
+BeginEndDistanceIs(const DistanceMatcher& distance_matcher) {
+  return internal::BeginEndDistanceIsMatcher<DistanceMatcher>(distance_matcher);
+}
+
+// Returns a matcher that matches an equal container.
+// This matcher behaves like Eq(), but in the event of mismatch lists the
+// values that are included in one container but not the other. (Duplicate
+// values and order differences are not explained.)
+template <typename Container>
+inline PolymorphicMatcher<internal::ContainerEqMatcher<  // NOLINT
+                            GTEST_REMOVE_CONST_(Container)> >
+    ContainerEq(const Container& rhs) {
+  // This following line is for working around a bug in MSVC 8.0,
+  // which causes Container to be a const type sometimes.
+  typedef GTEST_REMOVE_CONST_(Container) RawContainer;
+  return MakePolymorphicMatcher(
+      internal::ContainerEqMatcher<RawContainer>(rhs));
+}
+
+// Returns a matcher that matches a container that, when sorted using
+// the given comparator, matches container_matcher.
+template <typename Comparator, typename ContainerMatcher>
+inline internal::WhenSortedByMatcher<Comparator, ContainerMatcher>
+WhenSortedBy(const Comparator& comparator,
+             const ContainerMatcher& container_matcher) {
+  return internal::WhenSortedByMatcher<Comparator, ContainerMatcher>(
+      comparator, container_matcher);
+}
+
+// Returns a matcher that matches a container that, when sorted using
+// the < operator, matches container_matcher.
+template <typename ContainerMatcher>
+inline internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher>
+WhenSorted(const ContainerMatcher& container_matcher) {
+  return
+      internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher>(
+          internal::LessComparator(), container_matcher);
+}
+
+// Matches an STL-style container or a native array that contains the
+// same number of elements as in rhs, where its i-th element and rhs's
+// i-th element (as a pair) satisfy the given pair matcher, for all i.
+// TupleMatcher must be able to be safely cast to Matcher<std::tuple<const
+// T1&, const T2&> >, where T1 and T2 are the types of elements in the
+// LHS container and the RHS container respectively.
+template <typename TupleMatcher, typename Container>
+inline internal::PointwiseMatcher<TupleMatcher,
+                                  GTEST_REMOVE_CONST_(Container)>
+Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) {
+  // This following line is for working around a bug in MSVC 8.0,
+  // which causes Container to be a const type sometimes (e.g. when
+  // rhs is a const int[])..
+  typedef GTEST_REMOVE_CONST_(Container) RawContainer;
+  return internal::PointwiseMatcher<TupleMatcher, RawContainer>(
+      tuple_matcher, rhs);
+}
+
+
+// Supports the Pointwise(m, {a, b, c}) syntax.
+template <typename TupleMatcher, typename T>
+inline internal::PointwiseMatcher<TupleMatcher, std::vector<T> > Pointwise(
+    const TupleMatcher& tuple_matcher, std::initializer_list<T> rhs) {
+  return Pointwise(tuple_matcher, std::vector<T>(rhs));
+}
+
+
+// UnorderedPointwise(pair_matcher, rhs) matches an STL-style
+// container or a native array that contains the same number of
+// elements as in rhs, where in some permutation of the container, its
+// i-th element and rhs's i-th element (as a pair) satisfy the given
+// pair matcher, for all i.  Tuple2Matcher must be able to be safely
+// cast to Matcher<std::tuple<const T1&, const T2&> >, where T1 and T2 are
+// the types of elements in the LHS container and the RHS container
+// respectively.
+//
+// This is like Pointwise(pair_matcher, rhs), except that the element
+// order doesn't matter.
+template <typename Tuple2Matcher, typename RhsContainer>
+inline internal::UnorderedElementsAreArrayMatcher<
+    typename internal::BoundSecondMatcher<
+        Tuple2Matcher, typename internal::StlContainerView<GTEST_REMOVE_CONST_(
+                           RhsContainer)>::type::value_type> >
+UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
+                   const RhsContainer& rhs_container) {
+  // This following line is for working around a bug in MSVC 8.0,
+  // which causes RhsContainer to be a const type sometimes (e.g. when
+  // rhs_container is a const int[]).
+  typedef GTEST_REMOVE_CONST_(RhsContainer) RawRhsContainer;
+
+  // RhsView allows the same code to handle RhsContainer being a
+  // STL-style container and it being a native C-style array.
+  typedef typename internal::StlContainerView<RawRhsContainer> RhsView;
+  typedef typename RhsView::type RhsStlContainer;
+  typedef typename RhsStlContainer::value_type Second;
+  const RhsStlContainer& rhs_stl_container =
+      RhsView::ConstReference(rhs_container);
+
+  // Create a matcher for each element in rhs_container.
+  ::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second> > matchers;
+  for (typename RhsStlContainer::const_iterator it = rhs_stl_container.begin();
+       it != rhs_stl_container.end(); ++it) {
+    matchers.push_back(
+        internal::MatcherBindSecond(tuple2_matcher, *it));
+  }
+
+  // Delegate the work to UnorderedElementsAreArray().
+  return UnorderedElementsAreArray(matchers);
+}
+
+
+// Supports the UnorderedPointwise(m, {a, b, c}) syntax.
+template <typename Tuple2Matcher, typename T>
+inline internal::UnorderedElementsAreArrayMatcher<
+    typename internal::BoundSecondMatcher<Tuple2Matcher, T> >
+UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
+                   std::initializer_list<T> rhs) {
+  return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs));
+}
+
+
+// Matches an STL-style container or a native array that contains at
+// least one element matching the given value or matcher.
+//
+// Examples:
+//   ::std::set<int> page_ids;
+//   page_ids.insert(3);
+//   page_ids.insert(1);
+//   EXPECT_THAT(page_ids, Contains(1));
+//   EXPECT_THAT(page_ids, Contains(Gt(2)));
+//   EXPECT_THAT(page_ids, Not(Contains(4)));
+//
+//   ::std::map<int, size_t> page_lengths;
+//   page_lengths[1] = 100;
+//   EXPECT_THAT(page_lengths,
+//               Contains(::std::pair<const int, size_t>(1, 100)));
+//
+//   const char* user_ids[] = { "joe", "mike", "tom" };
+//   EXPECT_THAT(user_ids, Contains(Eq(::std::string("tom"))));
+template <typename M>
+inline internal::ContainsMatcher<M> Contains(M matcher) {
+  return internal::ContainsMatcher<M>(matcher);
+}
+
+// IsSupersetOf(iterator_first, iterator_last)
+// IsSupersetOf(pointer, count)
+// IsSupersetOf(array)
+// IsSupersetOf(container)
+// IsSupersetOf({e1, e2, ..., en})
+//
+// IsSupersetOf() verifies that a surjective partial mapping onto a collection
+// of matchers exists. In other words, a container matches
+// IsSupersetOf({e1, ..., en}) if and only if there is a permutation
+// {y1, ..., yn} of some of the container's elements where y1 matches e1,
+// ..., and yn matches en. Obviously, the size of the container must be >= n
+// in order to have a match. Examples:
+//
+// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and
+//   1 matches Ne(0).
+// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches
+//   both Eq(1) and Lt(2). The reason is that different matchers must be used
+//   for elements in different slots of the container.
+// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches
+//   Eq(1) and (the second) 1 matches Lt(2).
+// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first)
+//   Gt(1) and 3 matches (the second) Gt(1).
+//
+// The matchers can be specified as an array, a pointer and count, a container,
+// an initializer list, or an STL iterator range. In each of these cases, the
+// underlying matchers can be either values or matchers.
+
+template <typename Iter>
+inline internal::UnorderedElementsAreArrayMatcher<
+    typename ::std::iterator_traits<Iter>::value_type>
+IsSupersetOf(Iter first, Iter last) {
+  typedef typename ::std::iterator_traits<Iter>::value_type T;
+  return internal::UnorderedElementsAreArrayMatcher<T>(
+      internal::UnorderedMatcherRequire::Superset, first, last);
+}
+
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
+    const T* pointer, size_t count) {
+  return IsSupersetOf(pointer, pointer + count);
+}
+
+template <typename T, size_t N>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
+    const T (&array)[N]) {
+  return IsSupersetOf(array, N);
+}
+
+template <typename Container>
+inline internal::UnorderedElementsAreArrayMatcher<
+    typename Container::value_type>
+IsSupersetOf(const Container& container) {
+  return IsSupersetOf(container.begin(), container.end());
+}
+
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
+    ::std::initializer_list<T> xs) {
+  return IsSupersetOf(xs.begin(), xs.end());
+}
+
+// IsSubsetOf(iterator_first, iterator_last)
+// IsSubsetOf(pointer, count)
+// IsSubsetOf(array)
+// IsSubsetOf(container)
+// IsSubsetOf({e1, e2, ..., en})
+//
+// IsSubsetOf() verifies that an injective mapping onto a collection of matchers
+// exists.  In other words, a container matches IsSubsetOf({e1, ..., en}) if and
+// only if there is a subset of matchers {m1, ..., mk} which would match the
+// container using UnorderedElementsAre.  Obviously, the size of the container
+// must be <= n in order to have a match. Examples:
+//
+// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0).
+// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1
+//   matches Lt(0).
+// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both
+//   match Gt(0). The reason is that different matchers must be used for
+//   elements in different slots of the container.
+//
+// The matchers can be specified as an array, a pointer and count, a container,
+// an initializer list, or an STL iterator range. In each of these cases, the
+// underlying matchers can be either values or matchers.
+
+template <typename Iter>
+inline internal::UnorderedElementsAreArrayMatcher<
+    typename ::std::iterator_traits<Iter>::value_type>
+IsSubsetOf(Iter first, Iter last) {
+  typedef typename ::std::iterator_traits<Iter>::value_type T;
+  return internal::UnorderedElementsAreArrayMatcher<T>(
+      internal::UnorderedMatcherRequire::Subset, first, last);
+}
+
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
+    const T* pointer, size_t count) {
+  return IsSubsetOf(pointer, pointer + count);
+}
+
+template <typename T, size_t N>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
+    const T (&array)[N]) {
+  return IsSubsetOf(array, N);
+}
+
+template <typename Container>
+inline internal::UnorderedElementsAreArrayMatcher<
+    typename Container::value_type>
+IsSubsetOf(const Container& container) {
+  return IsSubsetOf(container.begin(), container.end());
+}
+
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
+    ::std::initializer_list<T> xs) {
+  return IsSubsetOf(xs.begin(), xs.end());
+}
+
+// Matches an STL-style container or a native array that contains only
+// elements matching the given value or matcher.
+//
+// Each(m) is semantically equivalent to Not(Contains(Not(m))). Only
+// the messages are different.
+//
+// Examples:
+//   ::std::set<int> page_ids;
+//   // Each(m) matches an empty container, regardless of what m is.
+//   EXPECT_THAT(page_ids, Each(Eq(1)));
+//   EXPECT_THAT(page_ids, Each(Eq(77)));
+//
+//   page_ids.insert(3);
+//   EXPECT_THAT(page_ids, Each(Gt(0)));
+//   EXPECT_THAT(page_ids, Not(Each(Gt(4))));
+//   page_ids.insert(1);
+//   EXPECT_THAT(page_ids, Not(Each(Lt(2))));
+//
+//   ::std::map<int, size_t> page_lengths;
+//   page_lengths[1] = 100;
+//   page_lengths[2] = 200;
+//   page_lengths[3] = 300;
+//   EXPECT_THAT(page_lengths, Not(Each(Pair(1, 100))));
+//   EXPECT_THAT(page_lengths, Each(Key(Le(3))));
+//
+//   const char* user_ids[] = { "joe", "mike", "tom" };
+//   EXPECT_THAT(user_ids, Not(Each(Eq(::std::string("tom")))));
+template <typename M>
+inline internal::EachMatcher<M> Each(M matcher) {
+  return internal::EachMatcher<M>(matcher);
+}
+
+// Key(inner_matcher) matches an std::pair whose 'first' field matches
+// inner_matcher.  For example, Contains(Key(Ge(5))) can be used to match an
+// std::map that contains at least one element whose key is >= 5.
+template <typename M>
+inline internal::KeyMatcher<M> Key(M inner_matcher) {
+  return internal::KeyMatcher<M>(inner_matcher);
+}
+
+// Pair(first_matcher, second_matcher) matches a std::pair whose 'first' field
+// matches first_matcher and whose 'second' field matches second_matcher.  For
+// example, EXPECT_THAT(map_type, ElementsAre(Pair(Ge(5), "foo"))) can be used
+// to match a std::map<int, string> that contains exactly one element whose key
+// is >= 5 and whose value equals "foo".
+template <typename FirstMatcher, typename SecondMatcher>
+inline internal::PairMatcher<FirstMatcher, SecondMatcher>
+Pair(FirstMatcher first_matcher, SecondMatcher second_matcher) {
+  return internal::PairMatcher<FirstMatcher, SecondMatcher>(
+      first_matcher, second_matcher);
+}
+
+// Returns a predicate that is satisfied by anything that matches the
+// given matcher.
+template <typename M>
+inline internal::MatcherAsPredicate<M> Matches(M matcher) {
+  return internal::MatcherAsPredicate<M>(matcher);
+}
+
+// Returns true iff the value matches the matcher.
+template <typename T, typename M>
+inline bool Value(const T& value, M matcher) {
+  return testing::Matches(matcher)(value);
+}
+
+// Matches the value against the given matcher and explains the match
+// result to listener.
+template <typename T, typename M>
+inline bool ExplainMatchResult(
+    M matcher, const T& value, MatchResultListener* listener) {
+  return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener);
+}
+
+// Returns a string representation of the given matcher.  Useful for description
+// strings of matchers defined using MATCHER_P* macros that accept matchers as
+// their arguments.  For example:
+//
+// MATCHER_P(XAndYThat, matcher,
+//           "X that " + DescribeMatcher<int>(matcher, negation) +
+//               " and Y that " + DescribeMatcher<double>(matcher, negation)) {
+//   return ExplainMatchResult(matcher, arg.x(), result_listener) &&
+//          ExplainMatchResult(matcher, arg.y(), result_listener);
+// }
+template <typename T, typename M>
+std::string DescribeMatcher(const M& matcher, bool negation = false) {
+  ::std::stringstream ss;
+  Matcher<T> monomorphic_matcher = SafeMatcherCast<T>(matcher);
+  if (negation) {
+    monomorphic_matcher.DescribeNegationTo(&ss);
+  } else {
+    monomorphic_matcher.DescribeTo(&ss);
+  }
+  return ss.str();
+}
+
+template <typename... Args>
+internal::ElementsAreMatcher<
+    std::tuple<typename std::decay<const Args&>::type...>>
+ElementsAre(const Args&... matchers) {
+  return internal::ElementsAreMatcher<
+      std::tuple<typename std::decay<const Args&>::type...>>(
+      std::make_tuple(matchers...));
+}
+
+template <typename... Args>
+internal::UnorderedElementsAreMatcher<
+    std::tuple<typename std::decay<const Args&>::type...>>
+UnorderedElementsAre(const Args&... matchers) {
+  return internal::UnorderedElementsAreMatcher<
+      std::tuple<typename std::decay<const Args&>::type...>>(
+      std::make_tuple(matchers...));
+}
+
+// Define variadic matcher versions.
+template <typename... Args>
+internal::AllOfMatcher<typename std::decay<const Args&>::type...> AllOf(
+    const Args&... matchers) {
+  return internal::AllOfMatcher<typename std::decay<const Args&>::type...>(
+      matchers...);
+}
+
+template <typename... Args>
+internal::AnyOfMatcher<typename std::decay<const Args&>::type...> AnyOf(
+    const Args&... matchers) {
+  return internal::AnyOfMatcher<typename std::decay<const Args&>::type...>(
+      matchers...);
+}
+
+// AnyOfArray(array)
+// AnyOfArray(pointer, count)
+// AnyOfArray(container)
+// AnyOfArray({ e1, e2, ..., en })
+// AnyOfArray(iterator_first, iterator_last)
+//
+// AnyOfArray() verifies whether a given value matches any member of a
+// collection of matchers.
+//
+// AllOfArray(array)
+// AllOfArray(pointer, count)
+// AllOfArray(container)
+// AllOfArray({ e1, e2, ..., en })
+// AllOfArray(iterator_first, iterator_last)
+//
+// AllOfArray() verifies whether a given value matches all members of a
+// collection of matchers.
+//
+// The matchers can be specified as an array, a pointer and count, a container,
+// an initializer list, or an STL iterator range. In each of these cases, the
+// underlying matchers can be either values or matchers.
+
+template <typename Iter>
+inline internal::AnyOfArrayMatcher<
+    typename ::std::iterator_traits<Iter>::value_type>
+AnyOfArray(Iter first, Iter last) {
+  return internal::AnyOfArrayMatcher<
+      typename ::std::iterator_traits<Iter>::value_type>(first, last);
+}
+
+template <typename Iter>
+inline internal::AllOfArrayMatcher<
+    typename ::std::iterator_traits<Iter>::value_type>
+AllOfArray(Iter first, Iter last) {
+  return internal::AllOfArrayMatcher<
+      typename ::std::iterator_traits<Iter>::value_type>(first, last);
+}
+
+template <typename T>
+inline internal::AnyOfArrayMatcher<T> AnyOfArray(const T* ptr, size_t count) {
+  return AnyOfArray(ptr, ptr + count);
+}
+
+template <typename T>
+inline internal::AllOfArrayMatcher<T> AllOfArray(const T* ptr, size_t count) {
+  return AllOfArray(ptr, ptr + count);
+}
+
+template <typename T, size_t N>
+inline internal::AnyOfArrayMatcher<T> AnyOfArray(const T (&array)[N]) {
+  return AnyOfArray(array, N);
+}
+
+template <typename T, size_t N>
+inline internal::AllOfArrayMatcher<T> AllOfArray(const T (&array)[N]) {
+  return AllOfArray(array, N);
+}
+
+template <typename Container>
+inline internal::AnyOfArrayMatcher<typename Container::value_type> AnyOfArray(
+    const Container& container) {
+  return AnyOfArray(container.begin(), container.end());
+}
+
+template <typename Container>
+inline internal::AllOfArrayMatcher<typename Container::value_type> AllOfArray(
+    const Container& container) {
+  return AllOfArray(container.begin(), container.end());
+}
+
+template <typename T>
+inline internal::AnyOfArrayMatcher<T> AnyOfArray(
+    ::std::initializer_list<T> xs) {
+  return AnyOfArray(xs.begin(), xs.end());
+}
+
+template <typename T>
+inline internal::AllOfArrayMatcher<T> AllOfArray(
+    ::std::initializer_list<T> xs) {
+  return AllOfArray(xs.begin(), xs.end());
+}
+
+// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
+// fields of it matches a_matcher.  C++ doesn't support default
+// arguments for function templates, so we have to overload it.
+template <size_t... k, typename InnerMatcher>
+internal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...> Args(
+    InnerMatcher&& matcher) {
+  return internal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...>(
+      std::forward<InnerMatcher>(matcher));
+}
+
+// AllArgs(m) is a synonym of m.  This is useful in
+//
+//   EXPECT_CALL(foo, Bar(_, _)).With(AllArgs(Eq()));
+//
+// which is easier to read than
+//
+//   EXPECT_CALL(foo, Bar(_, _)).With(Eq());
+template <typename InnerMatcher>
+inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
+
+// Returns a matcher that matches the value of an optional<> type variable.
+// The matcher implementation only uses '!arg' and requires that the optional<>
+// type has a 'value_type' member type and that '*arg' is of type 'value_type'
+// and is printable using 'PrintToString'. It is compatible with
+// std::optional/std::experimental::optional.
+// Note that to compare an optional type variable against nullopt you should
+// use Eq(nullopt) and not Optional(Eq(nullopt)). The latter implies that the
+// optional value contains an optional itself.
+template <typename ValueMatcher>
+inline internal::OptionalMatcher<ValueMatcher> Optional(
+    const ValueMatcher& value_matcher) {
+  return internal::OptionalMatcher<ValueMatcher>(value_matcher);
+}
+
+// Returns a matcher that matches the value of a absl::any type variable.
+template <typename T>
+PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T> > AnyWith(
+    const Matcher<const T&>& matcher) {
+  return MakePolymorphicMatcher(
+      internal::any_cast_matcher::AnyCastMatcher<T>(matcher));
+}
+
+// Returns a matcher that matches the value of a variant<> type variable.
+// The matcher implementation uses ADL to find the holds_alternative and get
+// functions.
+// It is compatible with std::variant.
+template <typename T>
+PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
+    const Matcher<const T&>& matcher) {
+  return MakePolymorphicMatcher(
+      internal::variant_matcher::VariantMatcher<T>(matcher));
+}
+
+// These macros allow using matchers to check values in Google Test
+// tests.  ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
+// succeed iff the value matches the matcher.  If the assertion fails,
+// the value and the description of the matcher will be printed.
+#define ASSERT_THAT(value, matcher) ASSERT_PRED_FORMAT1(\
+    ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
+#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\
+    ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
+
+}  // namespace testing
+
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251 5046
+
+// Include any custom callback matchers added by the local installation.
+// We must include this header at the end to make sure it can use the
+// declarations from this file.
+// Copyright 2015, 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.
+//
+// Injection point for custom user configurations. See README for details
+//
+// GOOGLETEST_CM0002 DO NOT DELETE
+
+#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
+#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
+#endif  // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
+
+#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
+
+#if GTEST_HAS_EXCEPTIONS
+# include <stdexcept>  // NOLINT
+#endif
+
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
+namespace testing {
+
+// An abstract handle of an expectation.
+class Expectation;
+
+// A set of expectation handles.
+class ExpectationSet;
+
+// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
+// and MUST NOT BE USED IN USER CODE!!!
+namespace internal {
+
+// Implements a mock function.
+template <typename F> class FunctionMocker;
+
+// Base class for expectations.
+class ExpectationBase;
+
+// Implements an expectation.
+template <typename F> class TypedExpectation;
+
+// Helper class for testing the Expectation class template.
+class ExpectationTester;
+
+// Protects the mock object registry (in class Mock), all function
+// mockers, and all expectations.
+//
+// The reason we don't use more fine-grained protection is: when a
+// mock function Foo() is called, it needs to consult its expectations
+// to see which one should be picked.  If another thread is allowed to
+// call a mock function (either Foo() or a different one) at the same
+// time, it could affect the "retired" attributes of Foo()'s
+// expectations when InSequence() is used, and thus affect which
+// expectation gets picked.  Therefore, we sequence all mock function
+// calls to ensure the integrity of the mock objects' states.
+GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex);
+
+// Untyped base class for ActionResultHolder<R>.
+class UntypedActionResultHolderBase;
+
+// Abstract base class of FunctionMocker.  This is the
+// type-agnostic part of the function mocker interface.  Its pure
+// virtual methods are implemented by FunctionMocker.
+class GTEST_API_ UntypedFunctionMockerBase {
+ public:
+  UntypedFunctionMockerBase();
+  virtual ~UntypedFunctionMockerBase();
+
+  // Verifies that all expectations on this mock function have been
+  // satisfied.  Reports one or more Google Test non-fatal failures
+  // and returns false if not.
+  bool VerifyAndClearExpectationsLocked()
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
+
+  // Clears the ON_CALL()s set on this mock function.
+  virtual void ClearDefaultActionsLocked()
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) = 0;
+
+  // In all of the following Untyped* functions, it's the caller's
+  // responsibility to guarantee the correctness of the arguments'
+  // types.
+
+  // Performs the default action with the given arguments and returns
+  // the action's result.  The call description string will be used in
+  // the error message to describe the call in the case the default
+  // action fails.
+  // L = *
+  virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
+      void* untyped_args, const std::string& call_description) const = 0;
+
+  // Performs the given action with the given arguments and returns
+  // the action's result.
+  // L = *
+  virtual UntypedActionResultHolderBase* UntypedPerformAction(
+      const void* untyped_action, void* untyped_args) const = 0;
+
+  // Writes a message that the call is uninteresting (i.e. neither
+  // explicitly expected nor explicitly unexpected) to the given
+  // ostream.
+  virtual void UntypedDescribeUninterestingCall(
+      const void* untyped_args,
+      ::std::ostream* os) const
+          GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;
+
+  // Returns the expectation that matches the given function arguments
+  // (or NULL is there's no match); when a match is found,
+  // untyped_action is set to point to the action that should be
+  // performed (or NULL if the action is "do default"), and
+  // is_excessive is modified to indicate whether the call exceeds the
+  // expected number.
+  virtual const ExpectationBase* UntypedFindMatchingExpectation(
+      const void* untyped_args,
+      const void** untyped_action, bool* is_excessive,
+      ::std::ostream* what, ::std::ostream* why)
+          GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;
+
+  // Prints the given function arguments to the ostream.
+  virtual void UntypedPrintArgs(const void* untyped_args,
+                                ::std::ostream* os) const = 0;
+
+  // Sets the mock object this mock method belongs to, and registers
+  // this information in the global mock registry.  Will be called
+  // whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
+  // method.
+  void RegisterOwner(const void* mock_obj)
+      GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
+
+  // Sets the mock object this mock method belongs to, and sets the
+  // name of the mock function.  Will be called upon each invocation
+  // of this mock function.
+  void SetOwnerAndName(const void* mock_obj, const char* name)
+      GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
+
+  // Returns the mock object this mock method belongs to.  Must be
+  // called after RegisterOwner() or SetOwnerAndName() has been
+  // called.
+  const void* MockObject() const
+      GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
+
+  // Returns the name of this mock method.  Must be called after
+  // SetOwnerAndName() has been called.
+  const char* Name() const
+      GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
+
+  // Returns the result of invoking this mock function with the given
+  // arguments.  This function can be safely called from multiple
+  // threads concurrently.  The caller is responsible for deleting the
+  // result.
+  UntypedActionResultHolderBase* UntypedInvokeWith(void* untyped_args)
+      GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
+
+ protected:
+  typedef std::vector<const void*> UntypedOnCallSpecs;
+
+  using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>;
+
+  // Returns an Expectation object that references and co-owns exp,
+  // which must be an expectation on this mock function.
+  Expectation GetHandleOf(ExpectationBase* exp);
+
+  // Address of the mock object this mock method belongs to.  Only
+  // valid after this mock method has been called or
+  // ON_CALL/EXPECT_CALL has been invoked on it.
+  const void* mock_obj_;  // Protected by g_gmock_mutex.
+
+  // Name of the function being mocked.  Only valid after this mock
+  // method has been called.
+  const char* name_;  // Protected by g_gmock_mutex.
+
+  // All default action specs for this function mocker.
+  UntypedOnCallSpecs untyped_on_call_specs_;
+
+  // All expectations for this function mocker.
+  //
+  // It's undefined behavior to interleave expectations (EXPECT_CALLs
+  // or ON_CALLs) and mock function calls.  Also, the order of
+  // expectations is important.  Therefore it's a logic race condition
+  // to read/write untyped_expectations_ concurrently.  In order for
+  // tools like tsan to catch concurrent read/write accesses to
+  // untyped_expectations, we deliberately leave accesses to it
+  // unprotected.
+  UntypedExpectations untyped_expectations_;
+};  // class UntypedFunctionMockerBase
+
+// Untyped base class for OnCallSpec<F>.
+class UntypedOnCallSpecBase {
+ public:
+  // The arguments are the location of the ON_CALL() statement.
+  UntypedOnCallSpecBase(const char* a_file, int a_line)
+      : file_(a_file), line_(a_line), last_clause_(kNone) {}
+
+  // Where in the source file was the default action spec defined?
+  const char* file() const { return file_; }
+  int line() const { return line_; }
+
+ protected:
+  // Gives each clause in the ON_CALL() statement a name.
+  enum Clause {
+    // Do not change the order of the enum members!  The run-time
+    // syntax checking relies on it.
+    kNone,
+    kWith,
+    kWillByDefault
+  };
+
+  // Asserts that the ON_CALL() statement has a certain property.
+  void AssertSpecProperty(bool property,
+                          const std::string& failure_message) const {
+    Assert(property, file_, line_, failure_message);
+  }
+
+  // Expects that the ON_CALL() statement has a certain property.
+  void ExpectSpecProperty(bool property,
+                          const std::string& failure_message) const {
+    Expect(property, file_, line_, failure_message);
+  }
+
+  const char* file_;
+  int line_;
+
+  // The last clause in the ON_CALL() statement as seen so far.
+  // Initially kNone and changes as the statement is parsed.
+  Clause last_clause_;
+};  // class UntypedOnCallSpecBase
+
+// This template class implements an ON_CALL spec.
+template <typename F>
+class OnCallSpec : public UntypedOnCallSpecBase {
+ public:
+  typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+  typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
+
+  // Constructs an OnCallSpec object from the information inside
+  // the parenthesis of an ON_CALL() statement.
+  OnCallSpec(const char* a_file, int a_line,
+             const ArgumentMatcherTuple& matchers)
+      : UntypedOnCallSpecBase(a_file, a_line),
+        matchers_(matchers),
+        // By default, extra_matcher_ should match anything.  However,
+        // we cannot initialize it with _ as that causes ambiguity between
+        // Matcher's copy and move constructor for some argument types.
+        extra_matcher_(A<const ArgumentTuple&>()) {}
+
+  // Implements the .With() clause.
+  OnCallSpec& With(const Matcher<const ArgumentTuple&>& m) {
+    // Makes sure this is called at most once.
+    ExpectSpecProperty(last_clause_ < kWith,
+                       ".With() cannot appear "
+                       "more than once in an ON_CALL().");
+    last_clause_ = kWith;
+
+    extra_matcher_ = m;
+    return *this;
+  }
+
+  // Implements the .WillByDefault() clause.
+  OnCallSpec& WillByDefault(const Action<F>& action) {
+    ExpectSpecProperty(last_clause_ < kWillByDefault,
+                       ".WillByDefault() must appear "
+                       "exactly once in an ON_CALL().");
+    last_clause_ = kWillByDefault;
+
+    ExpectSpecProperty(!action.IsDoDefault(),
+                       "DoDefault() cannot be used in ON_CALL().");
+    action_ = action;
+    return *this;
+  }
+
+  // Returns true iff the given arguments match the matchers.
+  bool Matches(const ArgumentTuple& args) const {
+    return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);
+  }
+
+  // Returns the action specified by the user.
+  const Action<F>& GetAction() const {
+    AssertSpecProperty(last_clause_ == kWillByDefault,
+                       ".WillByDefault() must appear exactly "
+                       "once in an ON_CALL().");
+    return action_;
+  }
+
+ private:
+  // The information in statement
+  //
+  //   ON_CALL(mock_object, Method(matchers))
+  //       .With(multi-argument-matcher)
+  //       .WillByDefault(action);
+  //
+  // is recorded in the data members like this:
+  //
+  //   source file that contains the statement => file_
+  //   line number of the statement            => line_
+  //   matchers                                => matchers_
+  //   multi-argument-matcher                  => extra_matcher_
+  //   action                                  => action_
+  ArgumentMatcherTuple matchers_;
+  Matcher<const ArgumentTuple&> extra_matcher_;
+  Action<F> action_;
+};  // class OnCallSpec
+
+// Possible reactions on uninteresting calls.
+enum CallReaction {
+  kAllow,
+  kWarn,
+  kFail,
+};
+
+}  // namespace internal
+
+// Utilities for manipulating mock objects.
+class GTEST_API_ Mock {
+ public:
+  // The following public methods can be called concurrently.
+
+  // Tells Google Mock to ignore mock_obj when checking for leaked
+  // mock objects.
+  static void AllowLeak(const void* mock_obj)
+      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+
+  // Verifies and clears all expectations on the given mock object.
+  // If the expectations aren't satisfied, generates one or more
+  // Google Test non-fatal failures and returns false.
+  static bool VerifyAndClearExpectations(void* mock_obj)
+      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+
+  // Verifies all expectations on the given mock object and clears its
+  // default actions and expectations.  Returns true iff the
+  // verification was successful.
+  static bool VerifyAndClear(void* mock_obj)
+      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+
+  // Returns whether the mock was created as a naggy mock (default)
+  static bool IsNaggy(void* mock_obj)
+      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+  // Returns whether the mock was created as a nice mock
+  static bool IsNice(void* mock_obj)
+      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+  // Returns whether the mock was created as a strict mock
+  static bool IsStrict(void* mock_obj)
+      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+
+ private:
+  friend class internal::UntypedFunctionMockerBase;
+
+  // Needed for a function mocker to register itself (so that we know
+  // how to clear a mock object).
+  template <typename F>
+  friend class internal::FunctionMocker;
+
+  template <typename M>
+  friend class NiceMock;
+
+  template <typename M>
+  friend class NaggyMock;
+
+  template <typename M>
+  friend class StrictMock;
+
+  // Tells Google Mock to allow uninteresting calls on the given mock
+  // object.
+  static void AllowUninterestingCalls(const void* mock_obj)
+      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+
+  // Tells Google Mock to warn the user about uninteresting calls on
+  // the given mock object.
+  static void WarnUninterestingCalls(const void* mock_obj)
+      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+
+  // Tells Google Mock to fail uninteresting calls on the given mock
+  // object.
+  static void FailUninterestingCalls(const void* mock_obj)
+      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+
+  // Tells Google Mock the given mock object is being destroyed and
+  // its entry in the call-reaction table should be removed.
+  static void UnregisterCallReaction(const void* mock_obj)
+      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+
+  // Returns the reaction Google Mock will have on uninteresting calls
+  // made on the given mock object.
+  static internal::CallReaction GetReactionOnUninterestingCalls(
+      const void* mock_obj)
+          GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+
+  // Verifies that all expectations on the given mock object have been
+  // satisfied.  Reports one or more Google Test non-fatal failures
+  // and returns false if not.
+  static bool VerifyAndClearExpectationsLocked(void* mock_obj)
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
+
+  // Clears all ON_CALL()s set on the given mock object.
+  static void ClearDefaultActionsLocked(void* mock_obj)
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
+
+  // Registers a mock object and a mock method it owns.
+  static void Register(
+      const void* mock_obj,
+      internal::UntypedFunctionMockerBase* mocker)
+          GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+
+  // Tells Google Mock where in the source code mock_obj is used in an
+  // ON_CALL or EXPECT_CALL.  In case mock_obj is leaked, this
+  // information helps the user identify which object it is.
+  static void RegisterUseByOnCallOrExpectCall(
+      const void* mock_obj, const char* file, int line)
+          GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+
+  // Unregisters a mock method; removes the owning mock object from
+  // the registry when the last mock method associated with it has
+  // been unregistered.  This is called only in the destructor of
+  // FunctionMocker.
+  static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
+};  // class Mock
+
+// An abstract handle of an expectation.  Useful in the .After()
+// clause of EXPECT_CALL() for setting the (partial) order of
+// expectations.  The syntax:
+//
+//   Expectation e1 = EXPECT_CALL(...)...;
+//   EXPECT_CALL(...).After(e1)...;
+//
+// sets two expectations where the latter can only be matched after
+// the former has been satisfied.
+//
+// Notes:
+//   - This class is copyable and has value semantics.
+//   - Constness is shallow: a const Expectation object itself cannot
+//     be modified, but the mutable methods of the ExpectationBase
+//     object it references can be called via expectation_base().
+
+class GTEST_API_ Expectation {
+ public:
+  // Constructs a null object that doesn't reference any expectation.
+  Expectation();
+
+  ~Expectation();
+
+  // This single-argument ctor must not be explicit, in order to support the
+  //   Expectation e = EXPECT_CALL(...);
+  // syntax.
+  //
+  // A TypedExpectation object stores its pre-requisites as
+  // Expectation objects, and needs to call the non-const Retire()
+  // method on the ExpectationBase objects they reference.  Therefore
+  // Expectation must receive a *non-const* reference to the
+  // ExpectationBase object.
+  Expectation(internal::ExpectationBase& exp);  // NOLINT
+
+  // The compiler-generated copy ctor and operator= work exactly as
+  // intended, so we don't need to define our own.
+
+  // Returns true iff rhs references the same expectation as this object does.
+  bool operator==(const Expectation& rhs) const {
+    return expectation_base_ == rhs.expectation_base_;
+  }
+
+  bool operator!=(const Expectation& rhs) const { return !(*this == rhs); }
+
+ private:
+  friend class ExpectationSet;
+  friend class Sequence;
+  friend class ::testing::internal::ExpectationBase;
+  friend class ::testing::internal::UntypedFunctionMockerBase;
+
+  template <typename F>
+  friend class ::testing::internal::FunctionMocker;
+
+  template <typename F>
+  friend class ::testing::internal::TypedExpectation;
+
+  // This comparator is needed for putting Expectation objects into a set.
+  class Less {
+   public:
+    bool operator()(const Expectation& lhs, const Expectation& rhs) const {
+      return lhs.expectation_base_.get() < rhs.expectation_base_.get();
+    }
+  };
+
+  typedef ::std::set<Expectation, Less> Set;
+
+  Expectation(
+      const std::shared_ptr<internal::ExpectationBase>& expectation_base);
+
+  // Returns the expectation this object references.
+  const std::shared_ptr<internal::ExpectationBase>& expectation_base() const {
+    return expectation_base_;
+  }
+
+  // A shared_ptr that co-owns the expectation this handle references.
+  std::shared_ptr<internal::ExpectationBase> expectation_base_;
+};
+
+// A set of expectation handles.  Useful in the .After() clause of
+// EXPECT_CALL() for setting the (partial) order of expectations.  The
+// syntax:
+//
+//   ExpectationSet es;
+//   es += EXPECT_CALL(...)...;
+//   es += EXPECT_CALL(...)...;
+//   EXPECT_CALL(...).After(es)...;
+//
+// sets three expectations where the last one can only be matched
+// after the first two have both been satisfied.
+//
+// This class is copyable and has value semantics.
+class ExpectationSet {
+ public:
+  // A bidirectional iterator that can read a const element in the set.
+  typedef Expectation::Set::const_iterator const_iterator;
+
+  // An object stored in the set.  This is an alias of Expectation.
+  typedef Expectation::Set::value_type value_type;
+
+  // Constructs an empty set.
+  ExpectationSet() {}
+
+  // This single-argument ctor must not be explicit, in order to support the
+  //   ExpectationSet es = EXPECT_CALL(...);
+  // syntax.
+  ExpectationSet(internal::ExpectationBase& exp) {  // NOLINT
+    *this += Expectation(exp);
+  }
+
+  // This single-argument ctor implements implicit conversion from
+  // Expectation and thus must not be explicit.  This allows either an
+  // Expectation or an ExpectationSet to be used in .After().
+  ExpectationSet(const Expectation& e) {  // NOLINT
+    *this += e;
+  }
+
+  // The compiler-generator ctor and operator= works exactly as
+  // intended, so we don't need to define our own.
+
+  // Returns true iff rhs contains the same set of Expectation objects
+  // as this does.
+  bool operator==(const ExpectationSet& rhs) const {
+    return expectations_ == rhs.expectations_;
+  }
+
+  bool operator!=(const ExpectationSet& rhs) const { return !(*this == rhs); }
+
+  // Implements the syntax
+  //   expectation_set += EXPECT_CALL(...);
+  ExpectationSet& operator+=(const Expectation& e) {
+    expectations_.insert(e);
+    return *this;
+  }
+
+  int size() const { return static_cast<int>(expectations_.size()); }
+
+  const_iterator begin() const { return expectations_.begin(); }
+  const_iterator end() const { return expectations_.end(); }
+
+ private:
+  Expectation::Set expectations_;
+};
+
+
+// Sequence objects are used by a user to specify the relative order
+// in which the expectations should match.  They are copyable (we rely
+// on the compiler-defined copy constructor and assignment operator).
+class GTEST_API_ Sequence {
+ public:
+  // Constructs an empty sequence.
+  Sequence() : last_expectation_(new Expectation) {}
+
+  // Adds an expectation to this sequence.  The caller must ensure
+  // that no other thread is accessing this Sequence object.
+  void AddExpectation(const Expectation& expectation) const;
+
+ private:
+  // The last expectation in this sequence.
+  std::shared_ptr<Expectation> last_expectation_;
+};  // class Sequence
+
+// An object of this type causes all EXPECT_CALL() statements
+// encountered in its scope to be put in an anonymous sequence.  The
+// work is done in the constructor and destructor.  You should only
+// create an InSequence object on the stack.
+//
+// The sole purpose for this class is to support easy definition of
+// sequential expectations, e.g.
+//
+//   {
+//     InSequence dummy;  // The name of the object doesn't matter.
+//
+//     // The following expectations must match in the order they appear.
+//     EXPECT_CALL(a, Bar())...;
+//     EXPECT_CALL(a, Baz())...;
+//     ...
+//     EXPECT_CALL(b, Xyz())...;
+//   }
+//
+// You can create InSequence objects in multiple threads, as long as
+// they are used to affect different mock objects.  The idea is that
+// each thread can create and set up its own mocks as if it's the only
+// thread.  However, for clarity of your tests we recommend you to set
+// up mocks in the main thread unless you have a good reason not to do
+// so.
+class GTEST_API_ InSequence {
+ public:
+  InSequence();
+  ~InSequence();
+ private:
+  bool sequence_created_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(InSequence);  // NOLINT
+} GTEST_ATTRIBUTE_UNUSED_;
+
+namespace internal {
+
+// Points to the implicit sequence introduced by a living InSequence
+// object (if any) in the current thread or NULL.
+GTEST_API_ extern ThreadLocal<Sequence*> g_gmock_implicit_sequence;
+
+// Base class for implementing expectations.
+//
+// There are two reasons for having a type-agnostic base class for
+// Expectation:
+//
+//   1. We need to store collections of expectations of different
+//   types (e.g. all pre-requisites of a particular expectation, all
+//   expectations in a sequence).  Therefore these expectation objects
+//   must share a common base class.
+//
+//   2. We can avoid binary code bloat by moving methods not depending
+//   on the template argument of Expectation to the base class.
+//
+// This class is internal and mustn't be used by user code directly.
+class GTEST_API_ ExpectationBase {
+ public:
+  // source_text is the EXPECT_CALL(...) source that created this Expectation.
+  ExpectationBase(const char* file, int line, const std::string& source_text);
+
+  virtual ~ExpectationBase();
+
+  // Where in the source file was the expectation spec defined?
+  const char* file() const { return file_; }
+  int line() const { return line_; }
+  const char* source_text() const { return source_text_.c_str(); }
+  // Returns the cardinality specified in the expectation spec.
+  const Cardinality& cardinality() const { return cardinality_; }
+
+  // Describes the source file location of this expectation.
+  void DescribeLocationTo(::std::ostream* os) const {
+    *os << FormatFileLocation(file(), line()) << " ";
+  }
+
+  // Describes how many times a function call matching this
+  // expectation has occurred.
+  void DescribeCallCountTo(::std::ostream* os) const
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
+
+  // If this mock method has an extra matcher (i.e. .With(matcher)),
+  // describes it to the ostream.
+  virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) = 0;
+
+ protected:
+  friend class ::testing::Expectation;
+  friend class UntypedFunctionMockerBase;
+
+  enum Clause {
+    // Don't change the order of the enum members!
+    kNone,
+    kWith,
+    kTimes,
+    kInSequence,
+    kAfter,
+    kWillOnce,
+    kWillRepeatedly,
+    kRetiresOnSaturation
+  };
+
+  typedef std::vector<const void*> UntypedActions;
+
+  // Returns an Expectation object that references and co-owns this
+  // expectation.
+  virtual Expectation GetHandle() = 0;
+
+  // Asserts that the EXPECT_CALL() statement has the given property.
+  void AssertSpecProperty(bool property,
+                          const std::string& failure_message) const {
+    Assert(property, file_, line_, failure_message);
+  }
+
+  // Expects that the EXPECT_CALL() statement has the given property.
+  void ExpectSpecProperty(bool property,
+                          const std::string& failure_message) const {
+    Expect(property, file_, line_, failure_message);
+  }
+
+  // Explicitly specifies the cardinality of this expectation.  Used
+  // by the subclasses to implement the .Times() clause.
+  void SpecifyCardinality(const Cardinality& cardinality);
+
+  // Returns true iff the user specified the cardinality explicitly
+  // using a .Times().
+  bool cardinality_specified() const { return cardinality_specified_; }
+
+  // Sets the cardinality of this expectation spec.
+  void set_cardinality(const Cardinality& a_cardinality) {
+    cardinality_ = a_cardinality;
+  }
+
+  // The following group of methods should only be called after the
+  // EXPECT_CALL() statement, and only when g_gmock_mutex is held by
+  // the current thread.
+
+  // Retires all pre-requisites of this expectation.
+  void RetireAllPreRequisites()
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
+
+  // Returns true iff this expectation is retired.
+  bool is_retired() const
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+    return retired_;
+  }
+
+  // Retires this expectation.
+  void Retire()
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+    retired_ = true;
+  }
+
+  // Returns true iff this expectation is satisfied.
+  bool IsSatisfied() const
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+    return cardinality().IsSatisfiedByCallCount(call_count_);
+  }
+
+  // Returns true iff this expectation is saturated.
+  bool IsSaturated() const
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+    return cardinality().IsSaturatedByCallCount(call_count_);
+  }
+
+  // Returns true iff this expectation is over-saturated.
+  bool IsOverSaturated() const
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+    return cardinality().IsOverSaturatedByCallCount(call_count_);
+  }
+
+  // Returns true iff all pre-requisites of this expectation are satisfied.
+  bool AllPrerequisitesAreSatisfied() const
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
+
+  // Adds unsatisfied pre-requisites of this expectation to 'result'.
+  void FindUnsatisfiedPrerequisites(ExpectationSet* result) const
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
+
+  // Returns the number this expectation has been invoked.
+  int call_count() const
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+    return call_count_;
+  }
+
+  // Increments the number this expectation has been invoked.
+  void IncrementCallCount()
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+    call_count_++;
+  }
+
+  // Checks the action count (i.e. the number of WillOnce() and
+  // WillRepeatedly() clauses) against the cardinality if this hasn't
+  // been done before.  Prints a warning if there are too many or too
+  // few actions.
+  void CheckActionCountIfNotDone() const
+      GTEST_LOCK_EXCLUDED_(mutex_);
+
+  friend class ::testing::Sequence;
+  friend class ::testing::internal::ExpectationTester;
+
+  template <typename Function>
+  friend class TypedExpectation;
+
+  // Implements the .Times() clause.
+  void UntypedTimes(const Cardinality& a_cardinality);
+
+  // This group of fields are part of the spec and won't change after
+  // an EXPECT_CALL() statement finishes.
+  const char* file_;          // The file that contains the expectation.
+  int line_;                  // The line number of the expectation.
+  const std::string source_text_;  // The EXPECT_CALL(...) source text.
+  // True iff the cardinality is specified explicitly.
+  bool cardinality_specified_;
+  Cardinality cardinality_;            // The cardinality of the expectation.
+  // The immediate pre-requisites (i.e. expectations that must be
+  // satisfied before this expectation can be matched) of this
+  // expectation.  We use std::shared_ptr in the set because we want an
+  // Expectation object to be co-owned by its FunctionMocker and its
+  // successors.  This allows multiple mock objects to be deleted at
+  // different times.
+  ExpectationSet immediate_prerequisites_;
+
+  // This group of fields are the current state of the expectation,
+  // and can change as the mock function is called.
+  int call_count_;  // How many times this expectation has been invoked.
+  bool retired_;    // True iff this expectation has retired.
+  UntypedActions untyped_actions_;
+  bool extra_matcher_specified_;
+  bool repeated_action_specified_;  // True if a WillRepeatedly() was specified.
+  bool retires_on_saturation_;
+  Clause last_clause_;
+  mutable bool action_count_checked_;  // Under mutex_.
+  mutable Mutex mutex_;  // Protects action_count_checked_.
+
+  GTEST_DISALLOW_ASSIGN_(ExpectationBase);
+};  // class ExpectationBase
+
+// Impements an expectation for the given function type.
+template <typename F>
+class TypedExpectation : public ExpectationBase {
+ public:
+  typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+  typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
+  typedef typename Function<F>::Result Result;
+
+  TypedExpectation(FunctionMocker<F>* owner, const char* a_file, int a_line,
+                   const std::string& a_source_text,
+                   const ArgumentMatcherTuple& m)
+      : ExpectationBase(a_file, a_line, a_source_text),
+        owner_(owner),
+        matchers_(m),
+        // By default, extra_matcher_ should match anything.  However,
+        // we cannot initialize it with _ as that causes ambiguity between
+        // Matcher's copy and move constructor for some argument types.
+        extra_matcher_(A<const ArgumentTuple&>()),
+        repeated_action_(DoDefault()) {}
+
+  ~TypedExpectation() override {
+    // Check the validity of the action count if it hasn't been done
+    // yet (for example, if the expectation was never used).
+    CheckActionCountIfNotDone();
+    for (UntypedActions::const_iterator it = untyped_actions_.begin();
+         it != untyped_actions_.end(); ++it) {
+      delete static_cast<const Action<F>*>(*it);
+    }
+  }
+
+  // Implements the .With() clause.
+  TypedExpectation& With(const Matcher<const ArgumentTuple&>& m) {
+    if (last_clause_ == kWith) {
+      ExpectSpecProperty(false,
+                         ".With() cannot appear "
+                         "more than once in an EXPECT_CALL().");
+    } else {
+      ExpectSpecProperty(last_clause_ < kWith,
+                         ".With() must be the first "
+                         "clause in an EXPECT_CALL().");
+    }
+    last_clause_ = kWith;
+
+    extra_matcher_ = m;
+    extra_matcher_specified_ = true;
+    return *this;
+  }
+
+  // Implements the .Times() clause.
+  TypedExpectation& Times(const Cardinality& a_cardinality) {
+    ExpectationBase::UntypedTimes(a_cardinality);
+    return *this;
+  }
+
+  // Implements the .Times() clause.
+  TypedExpectation& Times(int n) {
+    return Times(Exactly(n));
+  }
+
+  // Implements the .InSequence() clause.
+  TypedExpectation& InSequence(const Sequence& s) {
+    ExpectSpecProperty(last_clause_ <= kInSequence,
+                       ".InSequence() cannot appear after .After(),"
+                       " .WillOnce(), .WillRepeatedly(), or "
+                       ".RetiresOnSaturation().");
+    last_clause_ = kInSequence;
+
+    s.AddExpectation(GetHandle());
+    return *this;
+  }
+  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2) {
+    return InSequence(s1).InSequence(s2);
+  }
+  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,
+                               const Sequence& s3) {
+    return InSequence(s1, s2).InSequence(s3);
+  }
+  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,
+                               const Sequence& s3, const Sequence& s4) {
+    return InSequence(s1, s2, s3).InSequence(s4);
+  }
+  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,
+                               const Sequence& s3, const Sequence& s4,
+                               const Sequence& s5) {
+    return InSequence(s1, s2, s3, s4).InSequence(s5);
+  }
+
+  // Implements that .After() clause.
+  TypedExpectation& After(const ExpectationSet& s) {
+    ExpectSpecProperty(last_clause_ <= kAfter,
+                       ".After() cannot appear after .WillOnce(),"
+                       " .WillRepeatedly(), or "
+                       ".RetiresOnSaturation().");
+    last_clause_ = kAfter;
+
+    for (ExpectationSet::const_iterator it = s.begin(); it != s.end(); ++it) {
+      immediate_prerequisites_ += *it;
+    }
+    return *this;
+  }
+  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2) {
+    return After(s1).After(s2);
+  }
+  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,
+                          const ExpectationSet& s3) {
+    return After(s1, s2).After(s3);
+  }
+  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,
+                          const ExpectationSet& s3, const ExpectationSet& s4) {
+    return After(s1, s2, s3).After(s4);
+  }
+  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,
+                          const ExpectationSet& s3, const ExpectationSet& s4,
+                          const ExpectationSet& s5) {
+    return After(s1, s2, s3, s4).After(s5);
+  }
+
+  // Implements the .WillOnce() clause.
+  TypedExpectation& WillOnce(const Action<F>& action) {
+    ExpectSpecProperty(last_clause_ <= kWillOnce,
+                       ".WillOnce() cannot appear after "
+                       ".WillRepeatedly() or .RetiresOnSaturation().");
+    last_clause_ = kWillOnce;
+
+    untyped_actions_.push_back(new Action<F>(action));
+    if (!cardinality_specified()) {
+      set_cardinality(Exactly(static_cast<int>(untyped_actions_.size())));
+    }
+    return *this;
+  }
+
+  // Implements the .WillRepeatedly() clause.
+  TypedExpectation& WillRepeatedly(const Action<F>& action) {
+    if (last_clause_ == kWillRepeatedly) {
+      ExpectSpecProperty(false,
+                         ".WillRepeatedly() cannot appear "
+                         "more than once in an EXPECT_CALL().");
+    } else {
+      ExpectSpecProperty(last_clause_ < kWillRepeatedly,
+                         ".WillRepeatedly() cannot appear "
+                         "after .RetiresOnSaturation().");
+    }
+    last_clause_ = kWillRepeatedly;
+    repeated_action_specified_ = true;
+
+    repeated_action_ = action;
+    if (!cardinality_specified()) {
+      set_cardinality(AtLeast(static_cast<int>(untyped_actions_.size())));
+    }
+
+    // Now that no more action clauses can be specified, we check
+    // whether their count makes sense.
+    CheckActionCountIfNotDone();
+    return *this;
+  }
+
+  // Implements the .RetiresOnSaturation() clause.
+  TypedExpectation& RetiresOnSaturation() {
+    ExpectSpecProperty(last_clause_ < kRetiresOnSaturation,
+                       ".RetiresOnSaturation() cannot appear "
+                       "more than once.");
+    last_clause_ = kRetiresOnSaturation;
+    retires_on_saturation_ = true;
+
+    // Now that no more action clauses can be specified, we check
+    // whether their count makes sense.
+    CheckActionCountIfNotDone();
+    return *this;
+  }
+
+  // Returns the matchers for the arguments as specified inside the
+  // EXPECT_CALL() macro.
+  const ArgumentMatcherTuple& matchers() const {
+    return matchers_;
+  }
+
+  // Returns the matcher specified by the .With() clause.
+  const Matcher<const ArgumentTuple&>& extra_matcher() const {
+    return extra_matcher_;
+  }
+
+  // Returns the action specified by the .WillRepeatedly() clause.
+  const Action<F>& repeated_action() const { return repeated_action_; }
+
+  // If this mock method has an extra matcher (i.e. .With(matcher)),
+  // describes it to the ostream.
+  void MaybeDescribeExtraMatcherTo(::std::ostream* os) override {
+    if (extra_matcher_specified_) {
+      *os << "    Expected args: ";
+      extra_matcher_.DescribeTo(os);
+      *os << "\n";
+    }
+  }
+
+ private:
+  template <typename Function>
+  friend class FunctionMocker;
+
+  // Returns an Expectation object that references and co-owns this
+  // expectation.
+  Expectation GetHandle() override { return owner_->GetHandleOf(this); }
+
+  // The following methods will be called only after the EXPECT_CALL()
+  // statement finishes and when the current thread holds
+  // g_gmock_mutex.
+
+  // Returns true iff this expectation matches the given arguments.
+  bool Matches(const ArgumentTuple& args) const
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+    return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);
+  }
+
+  // Returns true iff this expectation should handle the given arguments.
+  bool ShouldHandleArguments(const ArgumentTuple& args) const
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+
+    // In case the action count wasn't checked when the expectation
+    // was defined (e.g. if this expectation has no WillRepeatedly()
+    // or RetiresOnSaturation() clause), we check it when the
+    // expectation is used for the first time.
+    CheckActionCountIfNotDone();
+    return !is_retired() && AllPrerequisitesAreSatisfied() && Matches(args);
+  }
+
+  // Describes the result of matching the arguments against this
+  // expectation to the given ostream.
+  void ExplainMatchResultTo(
+      const ArgumentTuple& args,
+      ::std::ostream* os) const
+          GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+
+    if (is_retired()) {
+      *os << "         Expected: the expectation is active\n"
+          << "           Actual: it is retired\n";
+    } else if (!Matches(args)) {
+      if (!TupleMatches(matchers_, args)) {
+        ExplainMatchFailureTupleTo(matchers_, args, os);
+      }
+      StringMatchResultListener listener;
+      if (!extra_matcher_.MatchAndExplain(args, &listener)) {
+        *os << "    Expected args: ";
+        extra_matcher_.DescribeTo(os);
+        *os << "\n           Actual: don't match";
+
+        internal::PrintIfNotEmpty(listener.str(), os);
+        *os << "\n";
+      }
+    } else if (!AllPrerequisitesAreSatisfied()) {
+      *os << "         Expected: all pre-requisites are satisfied\n"
+          << "           Actual: the following immediate pre-requisites "
+          << "are not satisfied:\n";
+      ExpectationSet unsatisfied_prereqs;
+      FindUnsatisfiedPrerequisites(&unsatisfied_prereqs);
+      int i = 0;
+      for (ExpectationSet::const_iterator it = unsatisfied_prereqs.begin();
+           it != unsatisfied_prereqs.end(); ++it) {
+        it->expectation_base()->DescribeLocationTo(os);
+        *os << "pre-requisite #" << i++ << "\n";
+      }
+      *os << "                   (end of pre-requisites)\n";
+    } else {
+      // This line is here just for completeness' sake.  It will never
+      // be executed as currently the ExplainMatchResultTo() function
+      // is called only when the mock function call does NOT match the
+      // expectation.
+      *os << "The call matches the expectation.\n";
+    }
+  }
+
+  // Returns the action that should be taken for the current invocation.
+  const Action<F>& GetCurrentAction(const FunctionMocker<F>* mocker,
+                                    const ArgumentTuple& args) const
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+    const int count = call_count();
+    Assert(count >= 1, __FILE__, __LINE__,
+           "call_count() is <= 0 when GetCurrentAction() is "
+           "called - this should never happen.");
+
+    const int action_count = static_cast<int>(untyped_actions_.size());
+    if (action_count > 0 && !repeated_action_specified_ &&
+        count > action_count) {
+      // If there is at least one WillOnce() and no WillRepeatedly(),
+      // we warn the user when the WillOnce() clauses ran out.
+      ::std::stringstream ss;
+      DescribeLocationTo(&ss);
+      ss << "Actions ran out in " << source_text() << "...\n"
+         << "Called " << count << " times, but only "
+         << action_count << " WillOnce()"
+         << (action_count == 1 ? " is" : "s are") << " specified - ";
+      mocker->DescribeDefaultActionTo(args, &ss);
+      Log(kWarning, ss.str(), 1);
+    }
+
+    return count <= action_count
+               ? *static_cast<const Action<F>*>(
+                     untyped_actions_[static_cast<size_t>(count - 1)])
+               : repeated_action();
+  }
+
+  // Given the arguments of a mock function call, if the call will
+  // over-saturate this expectation, returns the default action;
+  // otherwise, returns the next action in this expectation.  Also
+  // describes *what* happened to 'what', and explains *why* Google
+  // Mock does it to 'why'.  This method is not const as it calls
+  // IncrementCallCount().  A return value of NULL means the default
+  // action.
+  const Action<F>* GetActionForArguments(const FunctionMocker<F>* mocker,
+                                         const ArgumentTuple& args,
+                                         ::std::ostream* what,
+                                         ::std::ostream* why)
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+    if (IsSaturated()) {
+      // We have an excessive call.
+      IncrementCallCount();
+      *what << "Mock function called more times than expected - ";
+      mocker->DescribeDefaultActionTo(args, what);
+      DescribeCallCountTo(why);
+
+      return nullptr;
+    }
+
+    IncrementCallCount();
+    RetireAllPreRequisites();
+
+    if (retires_on_saturation_ && IsSaturated()) {
+      Retire();
+    }
+
+    // Must be done after IncrementCount()!
+    *what << "Mock function call matches " << source_text() <<"...\n";
+    return &(GetCurrentAction(mocker, args));
+  }
+
+  // All the fields below won't change once the EXPECT_CALL()
+  // statement finishes.
+  FunctionMocker<F>* const owner_;
+  ArgumentMatcherTuple matchers_;
+  Matcher<const ArgumentTuple&> extra_matcher_;
+  Action<F> repeated_action_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TypedExpectation);
+};  // class TypedExpectation
+
+// A MockSpec object is used by ON_CALL() or EXPECT_CALL() for
+// specifying the default behavior of, or expectation on, a mock
+// function.
+
+// Note: class MockSpec really belongs to the ::testing namespace.
+// However if we define it in ::testing, MSVC will complain when
+// classes in ::testing::internal declare it as a friend class
+// template.  To workaround this compiler bug, we define MockSpec in
+// ::testing::internal and import it into ::testing.
+
+// Logs a message including file and line number information.
+GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
+                                const char* file, int line,
+                                const std::string& message);
+
+template <typename F>
+class MockSpec {
+ public:
+  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
+  typedef typename internal::Function<F>::ArgumentMatcherTuple
+      ArgumentMatcherTuple;
+
+  // Constructs a MockSpec object, given the function mocker object
+  // that the spec is associated with.
+  MockSpec(internal::FunctionMocker<F>* function_mocker,
+           const ArgumentMatcherTuple& matchers)
+      : function_mocker_(function_mocker), matchers_(matchers) {}
+
+  // Adds a new default action spec to the function mocker and returns
+  // the newly created spec.
+  internal::OnCallSpec<F>& InternalDefaultActionSetAt(
+      const char* file, int line, const char* obj, const char* call) {
+    LogWithLocation(internal::kInfo, file, line,
+                    std::string("ON_CALL(") + obj + ", " + call + ") invoked");
+    return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
+  }
+
+  // Adds a new expectation spec to the function mocker and returns
+  // the newly created spec.
+  internal::TypedExpectation<F>& InternalExpectedAt(
+      const char* file, int line, const char* obj, const char* call) {
+    const std::string source_text(std::string("EXPECT_CALL(") + obj + ", " +
+                                  call + ")");
+    LogWithLocation(internal::kInfo, file, line, source_text + " invoked");
+    return function_mocker_->AddNewExpectation(
+        file, line, source_text, matchers_);
+  }
+
+  // This operator overload is used to swallow the superfluous parameter list
+  // introduced by the ON/EXPECT_CALL macros. See the macro comments for more
+  // explanation.
+  MockSpec<F>& operator()(const internal::WithoutMatchers&, void* const) {
+    return *this;
+  }
+
+ private:
+  template <typename Function>
+  friend class internal::FunctionMocker;
+
+  // The function mocker that owns this spec.
+  internal::FunctionMocker<F>* const function_mocker_;
+  // The argument matchers specified in the spec.
+  ArgumentMatcherTuple matchers_;
+
+  GTEST_DISALLOW_ASSIGN_(MockSpec);
+};  // class MockSpec
+
+// Wrapper type for generically holding an ordinary value or lvalue reference.
+// If T is not a reference type, it must be copyable or movable.
+// ReferenceOrValueWrapper<T> is movable, and will also be copyable unless
+// T is a move-only value type (which means that it will always be copyable
+// if the current platform does not support move semantics).
+//
+// The primary template defines handling for values, but function header
+// comments describe the contract for the whole template (including
+// specializations).
+template <typename T>
+class ReferenceOrValueWrapper {
+ public:
+  // Constructs a wrapper from the given value/reference.
+  explicit ReferenceOrValueWrapper(T value)
+      : value_(std::move(value)) {
+  }
+
+  // Unwraps and returns the underlying value/reference, exactly as
+  // originally passed. The behavior of calling this more than once on
+  // the same object is unspecified.
+  T Unwrap() { return std::move(value_); }
+
+  // Provides nondestructive access to the underlying value/reference.
+  // Always returns a const reference (more precisely,
+  // const RemoveReference<T>&). The behavior of calling this after
+  // calling Unwrap on the same object is unspecified.
+  const T& Peek() const {
+    return value_;
+  }
+
+ private:
+  T value_;
+};
+
+// Specialization for lvalue reference types. See primary template
+// for documentation.
+template <typename T>
+class ReferenceOrValueWrapper<T&> {
+ public:
+  // Workaround for debatable pass-by-reference lint warning (c-library-team
+  // policy precludes NOLINT in this context)
+  typedef T& reference;
+  explicit ReferenceOrValueWrapper(reference ref)
+      : value_ptr_(&ref) {}
+  T& Unwrap() { return *value_ptr_; }
+  const T& Peek() const { return *value_ptr_; }
+
+ private:
+  T* value_ptr_;
+};
+
+// MSVC warns about using 'this' in base member initializer list, so
+// we need to temporarily disable the warning.  We have to do it for
+// the entire class to suppress the warning, even though it's about
+// the constructor only.
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355)
+
+// C++ treats the void type specially.  For example, you cannot define
+// a void-typed variable or pass a void value to a function.
+// ActionResultHolder<T> holds a value of type T, where T must be a
+// copyable type or void (T doesn't need to be default-constructable).
+// It hides the syntactic difference between void and other types, and
+// is used to unify the code for invoking both void-returning and
+// non-void-returning mock functions.
+
+// Untyped base class for ActionResultHolder<T>.
+class UntypedActionResultHolderBase {
+ public:
+  virtual ~UntypedActionResultHolderBase() {}
+
+  // Prints the held value as an action's result to os.
+  virtual void PrintAsActionResult(::std::ostream* os) const = 0;
+};
+
+// This generic definition is used when T is not void.
+template <typename T>
+class ActionResultHolder : public UntypedActionResultHolderBase {
+ public:
+  // Returns the held value. Must not be called more than once.
+  T Unwrap() {
+    return result_.Unwrap();
+  }
+
+  // Prints the held value as an action's result to os.
+  void PrintAsActionResult(::std::ostream* os) const override {
+    *os << "\n          Returns: ";
+    // T may be a reference type, so we don't use UniversalPrint().
+    UniversalPrinter<T>::Print(result_.Peek(), os);
+  }
+
+  // Performs the given mock function's default action and returns the
+  // result in a new-ed ActionResultHolder.
+  template <typename F>
+  static ActionResultHolder* PerformDefaultAction(
+      const FunctionMocker<F>* func_mocker,
+      typename Function<F>::ArgumentTuple&& args,
+      const std::string& call_description) {
+    return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction(
+        std::move(args), call_description)));
+  }
+
+  // Performs the given action and returns the result in a new-ed
+  // ActionResultHolder.
+  template <typename F>
+  static ActionResultHolder* PerformAction(
+      const Action<F>& action, typename Function<F>::ArgumentTuple&& args) {
+    return new ActionResultHolder(
+        Wrapper(action.Perform(std::move(args))));
+  }
+
+ private:
+  typedef ReferenceOrValueWrapper<T> Wrapper;
+
+  explicit ActionResultHolder(Wrapper result)
+      : result_(std::move(result)) {
+  }
+
+  Wrapper result_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder);
+};
+
+// Specialization for T = void.
+template <>
+class ActionResultHolder<void> : public UntypedActionResultHolderBase {
+ public:
+  void Unwrap() { }
+
+  void PrintAsActionResult(::std::ostream* /* os */) const override {}
+
+  // Performs the given mock function's default action and returns ownership
+  // of an empty ActionResultHolder*.
+  template <typename F>
+  static ActionResultHolder* PerformDefaultAction(
+      const FunctionMocker<F>* func_mocker,
+      typename Function<F>::ArgumentTuple&& args,
+      const std::string& call_description) {
+    func_mocker->PerformDefaultAction(std::move(args), call_description);
+    return new ActionResultHolder;
+  }
+
+  // Performs the given action and returns ownership of an empty
+  // ActionResultHolder*.
+  template <typename F>
+  static ActionResultHolder* PerformAction(
+      const Action<F>& action, typename Function<F>::ArgumentTuple&& args) {
+    action.Perform(std::move(args));
+    return new ActionResultHolder;
+  }
+
+ private:
+  ActionResultHolder() {}
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder);
+};
+
+template <typename F>
+class FunctionMocker;
+
+template <typename R, typename... Args>
+class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
+  using F = R(Args...);
+
+ public:
+  using Result = R;
+  using ArgumentTuple = std::tuple<Args...>;
+  using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
+
+  FunctionMocker() {}
+
+  // There is no generally useful and implementable semantics of
+  // copying a mock object, so copying a mock is usually a user error.
+  // Thus we disallow copying function mockers.  If the user really
+  // wants to copy a mock object, they should implement their own copy
+  // operation, for example:
+  //
+  //   class MockFoo : public Foo {
+  //    public:
+  //     // Defines a copy constructor explicitly.
+  //     MockFoo(const MockFoo& src) {}
+  //     ...
+  //   };
+  FunctionMocker(const FunctionMocker&) = delete;
+  FunctionMocker& operator=(const FunctionMocker&) = delete;
+
+  // The destructor verifies that all expectations on this mock
+  // function have been satisfied.  If not, it will report Google Test
+  // non-fatal failures for the violations.
+  ~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+    MutexLock l(&g_gmock_mutex);
+    VerifyAndClearExpectationsLocked();
+    Mock::UnregisterLocked(this);
+    ClearDefaultActionsLocked();
+  }
+
+  // Returns the ON_CALL spec that matches this mock function with the
+  // given arguments; returns NULL if no matching ON_CALL is found.
+  // L = *
+  const OnCallSpec<F>* FindOnCallSpec(
+      const ArgumentTuple& args) const {
+    for (UntypedOnCallSpecs::const_reverse_iterator it
+             = untyped_on_call_specs_.rbegin();
+         it != untyped_on_call_specs_.rend(); ++it) {
+      const OnCallSpec<F>* spec = static_cast<const OnCallSpec<F>*>(*it);
+      if (spec->Matches(args))
+        return spec;
+    }
+
+    return nullptr;
+  }
+
+  // Performs the default action of this mock function on the given
+  // arguments and returns the result. Asserts (or throws if
+  // exceptions are enabled) with a helpful call descrption if there
+  // is no valid return value. This method doesn't depend on the
+  // mutable state of this object, and thus can be called concurrently
+  // without locking.
+  // L = *
+  Result PerformDefaultAction(ArgumentTuple&& args,
+                              const std::string& call_description) const {
+    const OnCallSpec<F>* const spec =
+        this->FindOnCallSpec(args);
+    if (spec != nullptr) {
+      return spec->GetAction().Perform(std::move(args));
+    }
+    const std::string message =
+        call_description +
+        "\n    The mock function has no default action "
+        "set, and its return type has no default value set.";
+#if GTEST_HAS_EXCEPTIONS
+    if (!DefaultValue<Result>::Exists()) {
+      throw std::runtime_error(message);
+    }
+#else
+    Assert(DefaultValue<Result>::Exists(), "", -1, message);
+#endif
+    return DefaultValue<Result>::Get();
+  }
+
+  // Performs the default action with the given arguments and returns
+  // the action's result.  The call description string will be used in
+  // the error message to describe the call in the case the default
+  // action fails.  The caller is responsible for deleting the result.
+  // L = *
+  UntypedActionResultHolderBase* UntypedPerformDefaultAction(
+      void* untyped_args,  // must point to an ArgumentTuple
+      const std::string& call_description) const override {
+    ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
+    return ResultHolder::PerformDefaultAction(this, std::move(*args),
+                                              call_description);
+  }
+
+  // Performs the given action with the given arguments and returns
+  // the action's result.  The caller is responsible for deleting the
+  // result.
+  // L = *
+  UntypedActionResultHolderBase* UntypedPerformAction(
+      const void* untyped_action, void* untyped_args) const override {
+    // Make a copy of the action before performing it, in case the
+    // action deletes the mock object (and thus deletes itself).
+    const Action<F> action = *static_cast<const Action<F>*>(untyped_action);
+    ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
+    return ResultHolder::PerformAction(action, std::move(*args));
+  }
+
+  // Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked():
+  // clears the ON_CALL()s set on this mock function.
+  void ClearDefaultActionsLocked() override
+      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+
+    // Deleting our default actions may trigger other mock objects to be
+    // deleted, for example if an action contains a reference counted smart
+    // pointer to that mock object, and that is the last reference. So if we
+    // delete our actions within the context of the global mutex we may deadlock
+    // when this method is called again. Instead, make a copy of the set of
+    // actions to delete, clear our set within the mutex, and then delete the
+    // actions outside of the mutex.
+    UntypedOnCallSpecs specs_to_delete;
+    untyped_on_call_specs_.swap(specs_to_delete);
+
+    g_gmock_mutex.Unlock();
+    for (UntypedOnCallSpecs::const_iterator it =
+             specs_to_delete.begin();
+         it != specs_to_delete.end(); ++it) {
+      delete static_cast<const OnCallSpec<F>*>(*it);
+    }
+
+    // Lock the mutex again, since the caller expects it to be locked when we
+    // return.
+    g_gmock_mutex.Lock();
+  }
+
+  // Returns the result of invoking this mock function with the given
+  // arguments.  This function can be safely called from multiple
+  // threads concurrently.
+  Result Invoke(Args... args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+    ArgumentTuple tuple(std::forward<Args>(args)...);
+    std::unique_ptr<ResultHolder> holder(DownCast_<ResultHolder*>(
+        this->UntypedInvokeWith(static_cast<void*>(&tuple))));
+    return holder->Unwrap();
+  }
+
+  MockSpec<F> With(Matcher<Args>... m) {
+    return MockSpec<F>(this, ::std::make_tuple(std::move(m)...));
+  }
+
+ protected:
+  template <typename Function>
+  friend class MockSpec;
+
+  typedef ActionResultHolder<Result> ResultHolder;
+
+  // Adds and returns a default action spec for this mock function.
+  OnCallSpec<F>& AddNewOnCallSpec(
+      const char* file, int line,
+      const ArgumentMatcherTuple& m)
+          GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+    Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
+    OnCallSpec<F>* const on_call_spec = new OnCallSpec<F>(file, line, m);
+    untyped_on_call_specs_.push_back(on_call_spec);
+    return *on_call_spec;
+  }
+
+  // Adds and returns an expectation spec for this mock function.
+  TypedExpectation<F>& AddNewExpectation(const char* file, int line,
+                                         const std::string& source_text,
+                                         const ArgumentMatcherTuple& m)
+      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+    Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
+    TypedExpectation<F>* const expectation =
+        new TypedExpectation<F>(this, file, line, source_text, m);
+    const std::shared_ptr<ExpectationBase> untyped_expectation(expectation);
+    // See the definition of untyped_expectations_ for why access to
+    // it is unprotected here.
+    untyped_expectations_.push_back(untyped_expectation);
+
+    // Adds this expectation into the implicit sequence if there is one.
+    Sequence* const implicit_sequence = g_gmock_implicit_sequence.get();
+    if (implicit_sequence != nullptr) {
+      implicit_sequence->AddExpectation(Expectation(untyped_expectation));
+    }
+
+    return *expectation;
+  }
+
+ private:
+  template <typename Func> friend class TypedExpectation;
+
+  // Some utilities needed for implementing UntypedInvokeWith().
+
+  // Describes what default action will be performed for the given
+  // arguments.
+  // L = *
+  void DescribeDefaultActionTo(const ArgumentTuple& args,
+                               ::std::ostream* os) const {
+    const OnCallSpec<F>* const spec = FindOnCallSpec(args);
+
+    if (spec == nullptr) {
+      *os << (internal::type_equals<Result, void>::value ?
+              "returning directly.\n" :
+              "returning default value.\n");
+    } else {
+      *os << "taking default action specified at:\n"
+          << FormatFileLocation(spec->file(), spec->line()) << "\n";
+    }
+  }
+
+  // Writes a message that the call is uninteresting (i.e. neither
+  // explicitly expected nor explicitly unexpected) to the given
+  // ostream.
+  void UntypedDescribeUninterestingCall(const void* untyped_args,
+                                        ::std::ostream* os) const override
+      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+    const ArgumentTuple& args =
+        *static_cast<const ArgumentTuple*>(untyped_args);
+    *os << "Uninteresting mock function call - ";
+    DescribeDefaultActionTo(args, os);
+    *os << "    Function call: " << Name();
+    UniversalPrint(args, os);
+  }
+
+  // Returns the expectation that matches the given function arguments
+  // (or NULL is there's no match); when a match is found,
+  // untyped_action is set to point to the action that should be
+  // performed (or NULL if the action is "do default"), and
+  // is_excessive is modified to indicate whether the call exceeds the
+  // expected number.
+  //
+  // Critical section: We must find the matching expectation and the
+  // corresponding action that needs to be taken in an ATOMIC
+  // transaction.  Otherwise another thread may call this mock
+  // method in the middle and mess up the state.
+  //
+  // However, performing the action has to be left out of the critical
+  // section.  The reason is that we have no control on what the
+  // action does (it can invoke an arbitrary user function or even a
+  // mock function) and excessive locking could cause a dead lock.
+  const ExpectationBase* UntypedFindMatchingExpectation(
+      const void* untyped_args, const void** untyped_action, bool* is_excessive,
+      ::std::ostream* what, ::std::ostream* why) override
+      GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+    const ArgumentTuple& args =
+        *static_cast<const ArgumentTuple*>(untyped_args);
+    MutexLock l(&g_gmock_mutex);
+    TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
+    if (exp == nullptr) {  // A match wasn't found.
+      this->FormatUnexpectedCallMessageLocked(args, what, why);
+      return nullptr;
+    }
+
+    // This line must be done before calling GetActionForArguments(),
+    // which will increment the call count for *exp and thus affect
+    // its saturation status.
+    *is_excessive = exp->IsSaturated();
+    const Action<F>* action = exp->GetActionForArguments(this, args, what, why);
+    if (action != nullptr && action->IsDoDefault())
+      action = nullptr;  // Normalize "do default" to NULL.
+    *untyped_action = action;
+    return exp;
+  }
+
+  // Prints the given function arguments to the ostream.
+  void UntypedPrintArgs(const void* untyped_args,
+                        ::std::ostream* os) const override {
+    const ArgumentTuple& args =
+        *static_cast<const ArgumentTuple*>(untyped_args);
+    UniversalPrint(args, os);
+  }
+
+  // Returns the expectation that matches the arguments, or NULL if no
+  // expectation matches them.
+  TypedExpectation<F>* FindMatchingExpectationLocked(
+      const ArgumentTuple& args) const
+          GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+    // See the definition of untyped_expectations_ for why access to
+    // it is unprotected here.
+    for (typename UntypedExpectations::const_reverse_iterator it =
+             untyped_expectations_.rbegin();
+         it != untyped_expectations_.rend(); ++it) {
+      TypedExpectation<F>* const exp =
+          static_cast<TypedExpectation<F>*>(it->get());
+      if (exp->ShouldHandleArguments(args)) {
+        return exp;
+      }
+    }
+    return nullptr;
+  }
+
+  // Returns a message that the arguments don't match any expectation.
+  void FormatUnexpectedCallMessageLocked(
+      const ArgumentTuple& args,
+      ::std::ostream* os,
+      ::std::ostream* why) const
+          GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+    *os << "\nUnexpected mock function call - ";
+    DescribeDefaultActionTo(args, os);
+    PrintTriedExpectationsLocked(args, why);
+  }
+
+  // Prints a list of expectations that have been tried against the
+  // current mock function call.
+  void PrintTriedExpectationsLocked(
+      const ArgumentTuple& args,
+      ::std::ostream* why) const
+          GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+    g_gmock_mutex.AssertHeld();
+    const size_t count = untyped_expectations_.size();
+    *why << "Google Mock tried the following " << count << " "
+         << (count == 1 ? "expectation, but it didn't match" :
+             "expectations, but none matched")
+         << ":\n";
+    for (size_t i = 0; i < count; i++) {
+      TypedExpectation<F>* const expectation =
+          static_cast<TypedExpectation<F>*>(untyped_expectations_[i].get());
+      *why << "\n";
+      expectation->DescribeLocationTo(why);
+      if (count > 1) {
+        *why << "tried expectation #" << i << ": ";
+      }
+      *why << expectation->source_text() << "...\n";
+      expectation->ExplainMatchResultTo(args, why);
+      expectation->DescribeCallCountTo(why);
+    }
+  }
+};  // class FunctionMocker
+
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4355
+
+// Reports an uninteresting call (whose description is in msg) in the
+// manner specified by 'reaction'.
+void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
+
+}  // namespace internal
+
+// A MockFunction<F> class has one mock method whose type is F.  It is
+// useful when you just want your test code to emit some messages and
+// have Google Mock verify the right messages are sent (and perhaps at
+// the right times).  For example, if you are exercising code:
+//
+//   Foo(1);
+//   Foo(2);
+//   Foo(3);
+//
+// and want to verify that Foo(1) and Foo(3) both invoke
+// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
+//
+// TEST(FooTest, InvokesBarCorrectly) {
+//   MyMock mock;
+//   MockFunction<void(string check_point_name)> check;
+//   {
+//     InSequence s;
+//
+//     EXPECT_CALL(mock, Bar("a"));
+//     EXPECT_CALL(check, Call("1"));
+//     EXPECT_CALL(check, Call("2"));
+//     EXPECT_CALL(mock, Bar("a"));
+//   }
+//   Foo(1);
+//   check.Call("1");
+//   Foo(2);
+//   check.Call("2");
+//   Foo(3);
+// }
+//
+// The expectation spec says that the first Bar("a") must happen
+// before check point "1", the second Bar("a") must happen after check
+// point "2", and nothing should happen between the two check
+// points. The explicit check points make it easy to tell which
+// Bar("a") is called by which call to Foo().
+//
+// MockFunction<F> can also be used to exercise code that accepts
+// std::function<F> callbacks. To do so, use AsStdFunction() method
+// to create std::function proxy forwarding to original object's Call.
+// Example:
+//
+// TEST(FooTest, RunsCallbackWithBarArgument) {
+//   MockFunction<int(string)> callback;
+//   EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
+//   Foo(callback.AsStdFunction());
+// }
+template <typename F>
+class MockFunction;
+
+template <typename R, typename... Args>
+class MockFunction<R(Args...)> {
+ public:
+  MockFunction() {}
+  MockFunction(const MockFunction&) = delete;
+  MockFunction& operator=(const MockFunction&) = delete;
+
+  std::function<R(Args...)> AsStdFunction() {
+    return [this](Args... args) -> R {
+      return this->Call(std::forward<Args>(args)...);
+    };
+  }
+
+  // Implementation detail: the expansion of the MOCK_METHOD macro.
+  R Call(Args... args) {
+    mock_.SetOwnerAndName(this, "Call");
+    return mock_.Invoke(std::forward<Args>(args)...);
+  }
+
+  internal::MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {
+    mock_.RegisterOwner(this);
+    return mock_.With(std::move(m)...);
+  }
+
+  internal::MockSpec<R(Args...)> gmock_Call(const internal::WithoutMatchers&,
+                                            R (*)(Args...)) {
+    return this->gmock_Call(::testing::A<Args>()...);
+  }
+
+ private:
+  mutable internal::FunctionMocker<R(Args...)> mock_;
+};
+
+// The style guide prohibits "using" statements in a namespace scope
+// inside a header file.  However, the MockSpec class template is
+// meant to be defined in the ::testing namespace.  The following line
+// is just a trick for working around a bug in MSVC 8.0, which cannot
+// handle it if we define MockSpec in ::testing.
+using internal::MockSpec;
+
+// Const(x) is a convenient function for obtaining a const reference
+// to x.  This is useful for setting expectations on an overloaded
+// const mock method, e.g.
+//
+//   class MockFoo : public FooInterface {
+//    public:
+//     MOCK_METHOD0(Bar, int());
+//     MOCK_CONST_METHOD0(Bar, int&());
+//   };
+//
+//   MockFoo foo;
+//   // Expects a call to non-const MockFoo::Bar().
+//   EXPECT_CALL(foo, Bar());
+//   // Expects a call to const MockFoo::Bar().
+//   EXPECT_CALL(Const(foo), Bar());
+template <typename T>
+inline const T& Const(const T& x) { return x; }
+
+// Constructs an Expectation object that references and co-owns exp.
+inline Expectation::Expectation(internal::ExpectationBase& exp)  // NOLINT
+    : expectation_base_(exp.GetHandle().expectation_base()) {}
+
+}  // namespace testing
+
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251
+
+// Implementation for ON_CALL and EXPECT_CALL macros. A separate macro is
+// required to avoid compile errors when the name of the method used in call is
+// a result of macro expansion. See CompilesWithMethodNameExpandedFromMacro
+// tests in internal/gmock-spec-builders_test.cc for more details.
+//
+// This macro supports statements both with and without parameter matchers. If
+// the parameter list is omitted, gMock will accept any parameters, which allows
+// tests to be written that don't need to encode the number of method
+// parameter. This technique may only be used for non-overloaded methods.
+//
+//   // These are the same:
+//   ON_CALL(mock, NoArgsMethod()).WillByDefault(...);
+//   ON_CALL(mock, NoArgsMethod).WillByDefault(...);
+//
+//   // As are these:
+//   ON_CALL(mock, TwoArgsMethod(_, _)).WillByDefault(...);
+//   ON_CALL(mock, TwoArgsMethod).WillByDefault(...);
+//
+//   // Can also specify args if you want, of course:
+//   ON_CALL(mock, TwoArgsMethod(_, 45)).WillByDefault(...);
+//
+//   // Overloads work as long as you specify parameters:
+//   ON_CALL(mock, OverloadedMethod(_)).WillByDefault(...);
+//   ON_CALL(mock, OverloadedMethod(_, _)).WillByDefault(...);
+//
+//   // Oops! Which overload did you want?
+//   ON_CALL(mock, OverloadedMethod).WillByDefault(...);
+//     => ERROR: call to member function 'gmock_OverloadedMethod' is ambiguous
+//
+// How this works: The mock class uses two overloads of the gmock_Method
+// expectation setter method plus an operator() overload on the MockSpec object.
+// In the matcher list form, the macro expands to:
+//
+//   // This statement:
+//   ON_CALL(mock, TwoArgsMethod(_, 45))...
+//
+//   // ...expands to:
+//   mock.gmock_TwoArgsMethod(_, 45)(WithoutMatchers(), nullptr)...
+//   |-------------v---------------||------------v-------------|
+//       invokes first overload        swallowed by operator()
+//
+//   // ...which is essentially:
+//   mock.gmock_TwoArgsMethod(_, 45)...
+//
+// Whereas the form without a matcher list:
+//
+//   // This statement:
+//   ON_CALL(mock, TwoArgsMethod)...
+//
+//   // ...expands to:
+//   mock.gmock_TwoArgsMethod(WithoutMatchers(), nullptr)...
+//   |-----------------------v--------------------------|
+//                 invokes second overload
+//
+//   // ...which is essentially:
+//   mock.gmock_TwoArgsMethod(_, _)...
+//
+// The WithoutMatchers() argument is used to disambiguate overloads and to
+// block the caller from accidentally invoking the second overload directly. The
+// second argument is an internal type derived from the method signature. The
+// failure to disambiguate two overloads of this method in the ON_CALL statement
+// is how we block callers from setting expectations on overloaded methods.
+#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call)                    \
+  ((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \
+                             nullptr)                                   \
+      .Setter(__FILE__, __LINE__, #mock_expr, #call)
+
+#define ON_CALL(obj, call) \
+  GMOCK_ON_CALL_IMPL_(obj, InternalDefaultActionSetAt, call)
+
+#define EXPECT_CALL(obj, call) \
+  GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call)
+
+#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
+
+namespace testing {
+namespace internal {
+// Removes the given pointer; this is a helper for the expectation setter method
+// for parameterless matchers.
+//
+// We want to make sure that the user cannot set a parameterless expectation on
+// overloaded methods, including methods which are overloaded on const. Example:
+//
+//   class MockClass {
+//     MOCK_METHOD0(GetName, string&());
+//     MOCK_CONST_METHOD0(GetName, const string&());
+//   };
+//
+//   TEST() {
+//     // This should be an error, as it's not clear which overload is expected.
+//     EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value));
+//   }
+//
+// Here are the generated expectation-setter methods:
+//
+//   class MockClass {
+//     // Overload 1
+//     MockSpec<string&()> gmock_GetName() { ... }
+//     // Overload 2. Declared const so that the compiler will generate an
+//     // error when trying to resolve between this and overload 4 in
+//     // 'gmock_GetName(WithoutMatchers(), nullptr)'.
+//     MockSpec<string&()> gmock_GetName(
+//         const WithoutMatchers&, const Function<string&()>*) const {
+//       // Removes const from this, calls overload 1
+//       return AdjustConstness_(this)->gmock_GetName();
+//     }
+//
+//     // Overload 3
+//     const string& gmock_GetName() const { ... }
+//     // Overload 4
+//     MockSpec<const string&()> gmock_GetName(
+//         const WithoutMatchers&, const Function<const string&()>*) const {
+//       // Does not remove const, calls overload 3
+//       return AdjustConstness_const(this)->gmock_GetName();
+//     }
+//   }
+//
+template <typename MockType>
+const MockType* AdjustConstness_const(const MockType* mock) {
+  return mock;
+}
+
+// Removes const from and returns the given pointer; this is a helper for the
+// expectation setter method for parameterless matchers.
+template <typename MockType>
+MockType* AdjustConstness_(const MockType* mock) {
+  return const_cast<MockType*>(mock);
+}
+
+}  // namespace internal
+
+// The style guide prohibits "using" statements in a namespace scope
+// inside a header file.  However, the FunctionMocker class template
+// is meant to be defined in the ::testing namespace.  The following
+// line is just a trick for working around a bug in MSVC 8.0, which
+// cannot handle it if we define FunctionMocker in ::testing.
+using internal::FunctionMocker;
+
+// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
+// We define this as a variadic macro in case F contains unprotected
+// commas (the same reason that we use variadic macros in other places
+// in this file).
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_RESULT_(tn, ...) \
+    tn ::testing::internal::Function<__VA_ARGS__>::Result
+
+// The type of argument N of the given function type.
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_ARG_(tn, N, ...) \
+    tn ::testing::internal::Function<__VA_ARGS__>::template Arg<N-1>::type
+
+// The matcher type for argument N of the given function type.
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_MATCHER_(tn, N, ...) \
+    const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
+
+// The variable for mocking the given method.
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_MOCKER_(arity, constness, Method) \
+    GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \
+  static_assert(0 == \
+      ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+      "MOCK_METHOD<N> must match argument count.");\
+  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
+      ) constness { \
+    GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \
+    return GMOCK_MOCKER_(0, constness, Method).Invoke(); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> \
+      gmock_##Method() constness { \
+    GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \
+    return GMOCK_MOCKER_(0, constness, Method).With(); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+      const ::testing::internal::WithoutMatchers&, \
+      constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+        return ::testing::internal::AdjustConstness_##constness(this)-> \
+            gmock_##Method(); \
+      } \
+  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \
+      Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \
+  static_assert(1 == \
+      ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+      "MOCK_METHOD<N> must match argument count.");\
+  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
+      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
+    GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \
+    return GMOCK_MOCKER_(1, constness, \
+        Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+        __VA_ARGS__)>(gmock_a1)); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> \
+      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
+    GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \
+    return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+      const ::testing::internal::WithoutMatchers&, \
+      constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+        return ::testing::internal::AdjustConstness_##constness(this)-> \
+            gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>()); \
+      } \
+  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \
+      Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \
+  static_assert(2 == \
+      ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+      "MOCK_METHOD<N> must match argument count.");\
+  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
+      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+          __VA_ARGS__) gmock_a2) constness { \
+    GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \
+    return GMOCK_MOCKER_(2, constness, \
+        Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+        __VA_ARGS__)>(gmock_a1), \
+  ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2)); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> \
+      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
+                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
+    GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \
+    return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+      const ::testing::internal::WithoutMatchers&, \
+      constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+        return ::testing::internal::AdjustConstness_##constness(this)-> \
+            gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>()); \
+      } \
+  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \
+      Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \
+  static_assert(3 == \
+      ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+      "MOCK_METHOD<N> must match argument count.");\
+  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
+      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+          __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, \
+          __VA_ARGS__) gmock_a3) constness { \
+    GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \
+    return GMOCK_MOCKER_(3, constness, \
+        Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+        __VA_ARGS__)>(gmock_a1), \
+  ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+  ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3)); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> \
+      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
+                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
+                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
+    GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \
+    return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \
+        gmock_a3); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+      const ::testing::internal::WithoutMatchers&, \
+      constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+        return ::testing::internal::AdjustConstness_##constness(this)-> \
+            gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>()); \
+      } \
+  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \
+      Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \
+  static_assert(4 == \
+      ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+      "MOCK_METHOD<N> must match argument count.");\
+  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
+      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+          __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+          GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
+    GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \
+    return GMOCK_MOCKER_(4, constness, \
+        Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+        __VA_ARGS__)>(gmock_a1), \
+  ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+  ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+  ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4)); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> \
+      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
+                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
+                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
+                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
+    GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \
+    return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \
+        gmock_a3, gmock_a4); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+      const ::testing::internal::WithoutMatchers&, \
+      constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+        return ::testing::internal::AdjustConstness_##constness(this)-> \
+            gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>()); \
+      } \
+  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \
+      Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \
+  static_assert(5 == \
+      ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+      "MOCK_METHOD<N> must match argument count.");\
+  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
+      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+          __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+          GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
+          __VA_ARGS__) gmock_a5) constness { \
+    GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \
+    return GMOCK_MOCKER_(5, constness, \
+        Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+        __VA_ARGS__)>(gmock_a1), \
+  ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+  ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+  ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
+  ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5)); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> \
+      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
+                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
+                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
+                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
+                     GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5) constness { \
+    GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \
+    return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \
+        gmock_a3, gmock_a4, gmock_a5); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+      const ::testing::internal::WithoutMatchers&, \
+      constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+        return ::testing::internal::AdjustConstness_##constness(this)-> \
+            gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>()); \
+      } \
+  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \
+      Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \
+  static_assert(6 == \
+      ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+      "MOCK_METHOD<N> must match argument count.");\
+  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
+      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+          __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+          GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
+          __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, \
+          __VA_ARGS__) gmock_a6) constness { \
+    GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \
+    return GMOCK_MOCKER_(6, constness, \
+        Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+        __VA_ARGS__)>(gmock_a1), \
+  ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+  ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+  ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
+  ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
+  ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6)); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> \
+      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
+                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
+                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
+                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
+                     GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
+                     GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6) constness { \
+    GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \
+    return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \
+        gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+      const ::testing::internal::WithoutMatchers&, \
+      constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+        return ::testing::internal::AdjustConstness_##constness(this)-> \
+            gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>()); \
+      } \
+  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \
+      Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \
+  static_assert(7 == \
+      ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+      "MOCK_METHOD<N> must match argument count.");\
+  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
+      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+          __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+          GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
+          __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
+          GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
+    GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \
+    return GMOCK_MOCKER_(7, constness, \
+        Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+        __VA_ARGS__)>(gmock_a1), \
+  ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+  ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+  ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
+  ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
+  ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
+  ::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7)); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> \
+      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
+                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
+                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
+                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
+                     GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
+                     GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
+                     GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
+    GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \
+    return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \
+        gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+      const ::testing::internal::WithoutMatchers&, \
+      constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+        return ::testing::internal::AdjustConstness_##constness(this)-> \
+            gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>()); \
+      } \
+  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \
+      Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \
+  static_assert(8 == \
+      ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+      "MOCK_METHOD<N> must match argument count.");\
+  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
+      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+          __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+          GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
+          __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
+          GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \
+          __VA_ARGS__) gmock_a8) constness { \
+    GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \
+    return GMOCK_MOCKER_(8, constness, \
+        Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+        __VA_ARGS__)>(gmock_a1), \
+  ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+  ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+  ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
+  ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
+  ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
+  ::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \
+  ::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8)); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> \
+      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
+                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
+                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
+                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
+                     GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
+                     GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
+                     GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
+                     GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8) constness { \
+    GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \
+    return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \
+        gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+      const ::testing::internal::WithoutMatchers&, \
+      constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+        return ::testing::internal::AdjustConstness_##constness(this)-> \
+            gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>()); \
+      } \
+  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \
+      Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \
+  static_assert(9 == \
+      ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+      "MOCK_METHOD<N> must match argument count.");\
+  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
+      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+          __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+          GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
+          __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
+          GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \
+          __VA_ARGS__) gmock_a8, GMOCK_ARG_(tn, 9, \
+          __VA_ARGS__) gmock_a9) constness { \
+    GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \
+    return GMOCK_MOCKER_(9, constness, \
+        Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+        __VA_ARGS__)>(gmock_a1), \
+  ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+  ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+  ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
+  ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
+  ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
+  ::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \
+  ::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8), \
+  ::std::forward<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(gmock_a9)); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> \
+      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
+                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
+                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
+                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
+                     GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
+                     GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
+                     GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
+                     GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
+                     GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9) constness { \
+    GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \
+    return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \
+        gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
+        gmock_a9); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+      const ::testing::internal::WithoutMatchers&, \
+      constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+        return ::testing::internal::AdjustConstness_##constness(this)-> \
+            gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 9, __VA_ARGS__)>()); \
+      } \
+  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \
+      Method)
+
+// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
+#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \
+  static_assert(10 == \
+      ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+      "MOCK_METHOD<N> must match argument count.");\
+  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
+      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+          __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+          GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
+          __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
+          GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \
+          __VA_ARGS__) gmock_a8, GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \
+          GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \
+    GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \
+    return GMOCK_MOCKER_(10, constness, \
+        Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+        __VA_ARGS__)>(gmock_a1), \
+  ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+  ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+  ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
+  ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
+  ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
+  ::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \
+  ::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8), \
+  ::std::forward<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(gmock_a9), \
+  ::std::forward<GMOCK_ARG_(tn, 10, __VA_ARGS__)>(gmock_a10)); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> \
+      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
+                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
+                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
+                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
+                     GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
+                     GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
+                     GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
+                     GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
+                     GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9, \
+                     GMOCK_MATCHER_(tn, 10, \
+                         __VA_ARGS__) gmock_a10) constness { \
+    GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \
+    return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \
+        gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
+        gmock_a10); \
+  } \
+  ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+      const ::testing::internal::WithoutMatchers&, \
+      constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+        return ::testing::internal::AdjustConstness_##constness(this)-> \
+            gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(), \
+                     ::testing::A<GMOCK_ARG_(tn, 10, __VA_ARGS__)>()); \
+      } \
+  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \
+      Method)
+
+#define MOCK_METHOD0(m, ...) GMOCK_METHOD0_(, , , m, __VA_ARGS__)
+#define MOCK_METHOD1(m, ...) GMOCK_METHOD1_(, , , m, __VA_ARGS__)
+#define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__)
+#define MOCK_METHOD3(m, ...) GMOCK_METHOD3_(, , , m, __VA_ARGS__)
+#define MOCK_METHOD4(m, ...) GMOCK_METHOD4_(, , , m, __VA_ARGS__)
+#define MOCK_METHOD5(m, ...) GMOCK_METHOD5_(, , , m, __VA_ARGS__)
+#define MOCK_METHOD6(m, ...) GMOCK_METHOD6_(, , , m, __VA_ARGS__)
+#define MOCK_METHOD7(m, ...) GMOCK_METHOD7_(, , , m, __VA_ARGS__)
+#define MOCK_METHOD8(m, ...) GMOCK_METHOD8_(, , , m, __VA_ARGS__)
+#define MOCK_METHOD9(m, ...) GMOCK_METHOD9_(, , , m, __VA_ARGS__)
+#define MOCK_METHOD10(m, ...) GMOCK_METHOD10_(, , , m, __VA_ARGS__)
+
+#define MOCK_CONST_METHOD0(m, ...) GMOCK_METHOD0_(, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD1(m, ...) GMOCK_METHOD1_(, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD3(m, ...) GMOCK_METHOD3_(, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD4(m, ...) GMOCK_METHOD4_(, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD5(m, ...) GMOCK_METHOD5_(, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD6(m, ...) GMOCK_METHOD6_(, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD7(m, ...) GMOCK_METHOD7_(, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD8(m, ...) GMOCK_METHOD8_(, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD9(m, ...) GMOCK_METHOD9_(, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD10(m, ...) GMOCK_METHOD10_(, const, , m, __VA_ARGS__)
+
+#define MOCK_METHOD0_T(m, ...) GMOCK_METHOD0_(typename, , , m, __VA_ARGS__)
+#define MOCK_METHOD1_T(m, ...) GMOCK_METHOD1_(typename, , , m, __VA_ARGS__)
+#define MOCK_METHOD2_T(m, ...) GMOCK_METHOD2_(typename, , , m, __VA_ARGS__)
+#define MOCK_METHOD3_T(m, ...) GMOCK_METHOD3_(typename, , , m, __VA_ARGS__)
+#define MOCK_METHOD4_T(m, ...) GMOCK_METHOD4_(typename, , , m, __VA_ARGS__)
+#define MOCK_METHOD5_T(m, ...) GMOCK_METHOD5_(typename, , , m, __VA_ARGS__)
+#define MOCK_METHOD6_T(m, ...) GMOCK_METHOD6_(typename, , , m, __VA_ARGS__)
+#define MOCK_METHOD7_T(m, ...) GMOCK_METHOD7_(typename, , , m, __VA_ARGS__)
+#define MOCK_METHOD8_T(m, ...) GMOCK_METHOD8_(typename, , , m, __VA_ARGS__)
+#define MOCK_METHOD9_T(m, ...) GMOCK_METHOD9_(typename, , , m, __VA_ARGS__)
+#define MOCK_METHOD10_T(m, ...) GMOCK_METHOD10_(typename, , , m, __VA_ARGS__)
+
+#define MOCK_CONST_METHOD0_T(m, ...) \
+    GMOCK_METHOD0_(typename, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD1_T(m, ...) \
+    GMOCK_METHOD1_(typename, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD2_T(m, ...) \
+    GMOCK_METHOD2_(typename, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD3_T(m, ...) \
+    GMOCK_METHOD3_(typename, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD4_T(m, ...) \
+    GMOCK_METHOD4_(typename, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD5_T(m, ...) \
+    GMOCK_METHOD5_(typename, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD6_T(m, ...) \
+    GMOCK_METHOD6_(typename, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD7_T(m, ...) \
+    GMOCK_METHOD7_(typename, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD8_T(m, ...) \
+    GMOCK_METHOD8_(typename, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD9_T(m, ...) \
+    GMOCK_METHOD9_(typename, const, , m, __VA_ARGS__)
+#define MOCK_CONST_METHOD10_T(m, ...) \
+    GMOCK_METHOD10_(typename, const, , m, __VA_ARGS__)
+
+#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD0_(, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD1_(, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD2_(, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD3_(, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD4_(, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD5_(, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD6_(, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD7_(, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD8_(, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD9_(, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD10_(, , ct, m, __VA_ARGS__)
+
+#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD0_(, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD1_(, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD2_(, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD3_(, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD4_(, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD5_(, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD6_(, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD7_(, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD8_(, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD9_(, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD10_(, const, ct, m, __VA_ARGS__)
+
+#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD0_(typename, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD1_(typename, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD2_(typename, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD3_(typename, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD4_(typename, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD5_(typename, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD6_(typename, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD7_(typename, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD8_(typename, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD9_(typename, , ct, m, __VA_ARGS__)
+#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD10_(typename, , ct, m, __VA_ARGS__)
+
+#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD0_(typename, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD1_(typename, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD2_(typename, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD3_(typename, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD4_(typename, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD5_(typename, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD6_(typename, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD7_(typename, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD8_(typename, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD9_(typename, const, ct, m, __VA_ARGS__)
+#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
+    GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__)
+
+}  // namespace testing
+
+#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
+#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
+#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
+
+#undef GMOCK_PP_INTERNAL_USE_MSVC
+#if defined(__clang__)
+#define GMOCK_PP_INTERNAL_USE_MSVC 0
+#elif defined(_MSC_VER)
+// TODO(iserna): Also verify tradional versus comformant preprocessor.
+static_assert(
+    _MSC_VER >= 1900,
+    "MSVC version not supported. There is support for MSVC 14.0 and above.");
+#define GMOCK_PP_INTERNAL_USE_MSVC 1
+#else
+#define GMOCK_PP_INTERNAL_USE_MSVC 0
+#endif
+
+// Expands and concatenates the arguments. Constructed macros reevaluate.
+#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)
+
+// Expands and stringifies the only argument.
+#define GMOCK_PP_STRINGIZE(...) GMOCK_PP_INTERNAL_STRINGIZE(__VA_ARGS__)
+
+// Returns empty. Given a variadic number of arguments.
+#define GMOCK_PP_EMPTY(...)
+
+// Returns a comma. Given a variadic number of arguments.
+#define GMOCK_PP_COMMA(...) ,
+
+// Returns the only argument.
+#define GMOCK_PP_IDENTITY(_1) _1
+
+// MSVC preprocessor collapses __VA_ARGS__ in a single argument, we use a
+// CAT-like directive to force correct evaluation. Each macro has its own.
+#if GMOCK_PP_INTERNAL_USE_MSVC
+
+// Evaluates to the number of arguments after expansion.
+//
+//   #define PAIR x, y
+//
+//   GMOCK_PP_NARG() => 1
+//   GMOCK_PP_NARG(x) => 1
+//   GMOCK_PP_NARG(x, y) => 2
+//   GMOCK_PP_NARG(PAIR) => 2
+//
+// Requires: the number of arguments after expansion is at most 15.
+#define GMOCK_PP_NARG(...)                                                    \
+  GMOCK_PP_INTERNAL_NARG_CAT(                                                 \
+      GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, \
+                                      8, 7, 6, 5, 4, 3, 2, 1), )
+
+// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise
+// returns 0. Requires no more than 15 unprotected commas.
+#define GMOCK_PP_HAS_COMMA(...)                                               \
+  GMOCK_PP_INTERNAL_HAS_COMMA_CAT(                                            \
+      GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+                                      1, 1, 1, 1, 1, 0), )
+// Returns the first argument.
+#define GMOCK_PP_HEAD(...) \
+  GMOCK_PP_INTERNAL_HEAD_CAT(GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__), )
+
+// Returns the tail. A variadic list of all arguments minus the first. Requires
+// at least one argument.
+#define GMOCK_PP_TAIL(...) \
+  GMOCK_PP_INTERNAL_TAIL_CAT(GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__), )
+
+// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)
+#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
+  GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT(      \
+      GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__), )
+
+#else  // GMOCK_PP_INTERNAL_USE_MSVC
+
+#define GMOCK_PP_NARG(...)                                                   \
+  GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, \
+                                  7, 6, 5, 4, 3, 2, 1)
+#define GMOCK_PP_HAS_COMMA(...)                                              \
+  GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+                                  1, 1, 1, 1, 0)
+#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__)
+#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__)
+#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
+  GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__)
+
+#endif  // GMOCK_PP_INTERNAL_USE_MSVC
+
+// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
+// evaluates to `0`.
+//
+// Requires: * the number of arguments after expansion is at most 15.
+//           * If the argument is a macro, it must be able to be called with one
+//             argument.
+//
+// Implementation details:
+//
+// There is one case when it generates a compile error: if the argument is macro
+// that cannot be called with one argument.
+//
+//   #define M(a, b)  // it doesn't matter what it expands to
+//
+//   // Expected: expands to `0`.
+//   // Actual: compile error.
+//   GMOCK_PP_IS_EMPTY(M)
+//
+// There are 4 cases tested:
+//
+// * __VA_ARGS__ possible expansion has no unparen'd commas. Expected 0.
+// * __VA_ARGS__ possible expansion is not enclosed in parenthesis. Expected 0.
+// * __VA_ARGS__ possible expansion is not a macro that ()-evaluates to a comma.
+//   Expected 0
+// * __VA_ARGS__ is empty, or has unparen'd commas, or is enclosed in
+//   parenthesis, or is a macro that ()-evaluates to comma. Expected 1.
+//
+// We trigger detection on '0001', i.e. on empty.
+#define GMOCK_PP_IS_EMPTY(...)                                               \
+  GMOCK_PP_INTERNAL_IS_EMPTY(GMOCK_PP_HAS_COMMA(__VA_ARGS__),                \
+                             GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__), \
+                             GMOCK_PP_HAS_COMMA(__VA_ARGS__()),              \
+                             GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__()))
+
+// Evaluates to _Then if _Cond is 1 and _Else if _Cond is 0.
+#define GMOCK_PP_IF(_Cond, _Then, _Else) \
+  GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else)
+
+// Evaluates to the number of arguments after expansion. Identifies 'empty' as
+// 0.
+//
+//   #define PAIR x, y
+//
+//   GMOCK_PP_NARG0() => 0
+//   GMOCK_PP_NARG0(x) => 1
+//   GMOCK_PP_NARG0(x, y) => 2
+//   GMOCK_PP_NARG0(PAIR) => 2
+//
+// Requires: * the number of arguments after expansion is at most 15.
+//           * If the argument is a macro, it must be able to be called with one
+//             argument.
+#define GMOCK_PP_NARG0(...) \
+  GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(__VA_ARGS__), 0, GMOCK_PP_NARG(__VA_ARGS__))
+
+// Expands to 1 if the first argument starts with something in parentheses,
+// otherwise to 0.
+#define GMOCK_PP_IS_BEGIN_PARENS(...)                    \
+  GMOCK_PP_INTERNAL_ALTERNATE_HEAD(                      \
+      GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
+                   GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
+
+// Expands to 1 is there is only one argument and it is enclosed in parentheses.
+#define GMOCK_PP_IS_ENCLOSED_PARENS(...)             \
+  GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(__VA_ARGS__), \
+              GMOCK_PP_IS_EMPTY(GMOCK_PP_EMPTY __VA_ARGS__), 0)
+
+// Remove the parens, requires GMOCK_PP_IS_ENCLOSED_PARENS(args) => 1.
+#define GMOCK_PP_REMOVE_PARENS(...) GMOCK_PP_INTERNAL_REMOVE_PARENS __VA_ARGS__
+
+// Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data,
+// eK) as many of GMOCK_INTERNAL_NARG0 _Tuple.
+// Requires: * |_Macro| can be called with 3 arguments.
+//           * |_Tuple| expansion has no more than 15 elements.
+#define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple)                        \
+  GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \
+  (0, _Macro, _Data, _Tuple)
+
+// Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, )
+// Empty if _K = 0.
+// Requires: * |_Macro| can be called with 3 arguments.
+//           * |_K| literal between 0 and 15
+#define GMOCK_PP_REPEAT(_Macro, _Data, _N)           \
+  GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \
+  (0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE)
+
+// Increments the argument, requires the argument to be between 0 and 15.
+#define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i)
+
+// Returns comma if _i != 0. Requires _i to be between 0 and 15.
+#define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i)
+
+// Internal details follow. Do not use any of these symbols outside of this
+// file or we will break your code.
+#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
+#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2
+#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__
+#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
+                                        _10, _11, _12, _13, _14, _15, _16,  \
+                                        ...)                                \
+  _16
+#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5
+#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4)                             \
+  GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \
+                                             _1, _2, _3, _4))
+#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,
+#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then
+#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else
+#define GMOCK_PP_INTERNAL_HEAD(_1, ...) _1
+#define GMOCK_PP_INTERNAL_TAIL(_1, ...) __VA_ARGS__
+
+#if GMOCK_PP_INTERNAL_USE_MSVC
+#define GMOCK_PP_INTERNAL_NARG_CAT(_1, _2) GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2)
+#define GMOCK_PP_INTERNAL_HEAD_CAT(_1, _2) GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2)
+#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT(_1, _2) \
+  GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2)
+#define GMOCK_PP_INTERNAL_TAIL_CAT(_1, _2) GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2)
+#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT(_1, _2) \
+  GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2)
+#define GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2) _1##_2
+#define GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2) _1##_2
+#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2) _1##_2
+#define GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2) _1##_2
+#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2) _1##_2
+#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) \
+  GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(GMOCK_PP_HEAD(__VA_ARGS__), )
+#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(_1, _2) \
+  GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2)
+#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2) _1##_2
+#else  // GMOCK_PP_INTERNAL_USE_MSVC
+#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) GMOCK_PP_HEAD(__VA_ARGS__)
+#endif  // GMOCK_PP_INTERNAL_USE_MSVC
+
+#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _
+#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
+#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C \
+  0,
+#define GMOCK_PP_INTERNAL_REMOVE_PARENS(...) __VA_ARGS__
+#define GMOCK_PP_INTERNAL_INC_0 1
+#define GMOCK_PP_INTERNAL_INC_1 2
+#define GMOCK_PP_INTERNAL_INC_2 3
+#define GMOCK_PP_INTERNAL_INC_3 4
+#define GMOCK_PP_INTERNAL_INC_4 5
+#define GMOCK_PP_INTERNAL_INC_5 6
+#define GMOCK_PP_INTERNAL_INC_6 7
+#define GMOCK_PP_INTERNAL_INC_7 8
+#define GMOCK_PP_INTERNAL_INC_8 9
+#define GMOCK_PP_INTERNAL_INC_9 10
+#define GMOCK_PP_INTERNAL_INC_10 11
+#define GMOCK_PP_INTERNAL_INC_11 12
+#define GMOCK_PP_INTERNAL_INC_12 13
+#define GMOCK_PP_INTERNAL_INC_13 14
+#define GMOCK_PP_INTERNAL_INC_14 15
+#define GMOCK_PP_INTERNAL_INC_15 16
+#define GMOCK_PP_INTERNAL_COMMA_IF_0
+#define GMOCK_PP_INTERNAL_COMMA_IF_1 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_2 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_3 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_4 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_5 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_6 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_7 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_8 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_9 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_10 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_11 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_12 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_13 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_14 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_15 ,
+#define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \
+  _Macro(_i, _Data, _element)
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple)
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(_i, _Macro, _Data, _Tuple) \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple)
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(_i, _Macro, _Data, _Tuple)    \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(GMOCK_PP_INC(_i), _Macro, _Data,    \
+                                    (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(_i, _Macro, _Data, _Tuple)    \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(GMOCK_PP_INC(_i), _Macro, _Data,    \
+                                    (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(_i, _Macro, _Data, _Tuple)    \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(GMOCK_PP_INC(_i), _Macro, _Data,    \
+                                    (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(_i, _Macro, _Data, _Tuple)    \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(GMOCK_PP_INC(_i), _Macro, _Data,    \
+                                    (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(_i, _Macro, _Data, _Tuple)    \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(GMOCK_PP_INC(_i), _Macro, _Data,    \
+                                    (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(_i, _Macro, _Data, _Tuple)    \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(GMOCK_PP_INC(_i), _Macro, _Data,    \
+                                    (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(_i, _Macro, _Data, _Tuple)    \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(GMOCK_PP_INC(_i), _Macro, _Data,    \
+                                    (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(_i, _Macro, _Data, _Tuple)    \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(GMOCK_PP_INC(_i), _Macro, _Data,    \
+                                    (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(_i, _Macro, _Data, _Tuple)   \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(GMOCK_PP_INC(_i), _Macro, _Data,    \
+                                    (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(_i, _Macro, _Data, _Tuple)   \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(GMOCK_PP_INC(_i), _Macro, _Data,   \
+                                     (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(_i, _Macro, _Data, _Tuple)   \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(GMOCK_PP_INC(_i), _Macro, _Data,   \
+                                     (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(_i, _Macro, _Data, _Tuple)   \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(GMOCK_PP_INC(_i), _Macro, _Data,   \
+                                     (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(_i, _Macro, _Data, _Tuple)   \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(GMOCK_PP_INC(_i), _Macro, _Data,   \
+                                     (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(_i, _Macro, _Data, _Tuple)   \
+  GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+  GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data,   \
+                                     (GMOCK_PP_TAIL _Tuple))
+
+#endif  // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
+
+#define MOCK_METHOD(...) \
+  GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__)
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \
+  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_2(...) \
+  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \
+  GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ())
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec)     \
+  GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args);                                   \
+  GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec);                                   \
+  GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(                                      \
+      GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args));           \
+  GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec)                                     \
+  GMOCK_INTERNAL_MOCK_METHOD_IMPL(                                            \
+      GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec),     \
+      GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec),    \
+      GMOCK_INTERNAL_HAS_NOEXCEPT(_Spec), GMOCK_INTERNAL_GET_CALLTYPE(_Spec), \
+      (GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
+  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_6(...) \
+  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_7(...) \
+  GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
+
+#define GMOCK_INTERNAL_WRONG_ARITY(...)                                      \
+  static_assert(                                                             \
+      false,                                                                 \
+      "MOCK_METHOD must be called with 3 or 4 arguments. _Ret, "             \
+      "_MethodName, _Args and optionally _Spec. _Args and _Spec must be "    \
+      "enclosed in parentheses. If _Ret is a type with unprotected commas, " \
+      "it must also be enclosed in parentheses.")
+
+#define GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Tuple) \
+  static_assert(                                  \
+      GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple),        \
+      GMOCK_PP_STRINGIZE(_Tuple) " should be enclosed in parentheses.")
+
+#define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...)                 \
+  static_assert(                                                       \
+      std::is_function<__VA_ARGS__>::value,                            \
+      "Signature must be a function type, maybe return type contains " \
+      "unprotected comma.");                                           \
+  static_assert(                                                       \
+      ::testing::tuple_size<typename ::testing::internal::Function<    \
+              __VA_ARGS__>::ArgumentTuple>::value == _N,               \
+      "This method does not take " GMOCK_PP_STRINGIZE(                 \
+          _N) " arguments. Parenthesize all types with unproctected commas.")
+
+#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
+  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec)
+
+#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness,           \
+                                        _Override, _Final, _Noexcept,          \
+                                        _CallType, _Signature)                 \
+  typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS(               \
+      _Signature)>::Result                                                     \
+  GMOCK_INTERNAL_EXPAND(_CallType)                                             \
+      _MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N))   \
+          GMOCK_PP_IF(_Constness, const, ) GMOCK_PP_IF(_Noexcept, noexcept, )  \
+              GMOCK_PP_IF(_Override, override, )                               \
+                  GMOCK_PP_IF(_Final, final, ) {                               \
+    GMOCK_MOCKER_(_N, _Constness, _MethodName)                                 \
+        .SetOwnerAndName(this, #_MethodName);                                  \
+    return GMOCK_MOCKER_(_N, _Constness, _MethodName)                          \
+        .Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N));  \
+  }                                                                            \
+  ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
+      GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N))       \
+      GMOCK_PP_IF(_Constness, const, ) {                                       \
+    GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this);            \
+    return GMOCK_MOCKER_(_N, _Constness, _MethodName)                          \
+        .With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N));         \
+  }                                                                            \
+  ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
+      const ::testing::internal::WithoutMatchers&,                             \
+      GMOCK_PP_IF(_Constness, const, )::testing::internal::Function<           \
+          GMOCK_PP_REMOVE_PARENS(_Signature)>*)                                \
+      const GMOCK_PP_IF(_Noexcept, noexcept, ) {                               \
+    return GMOCK_PP_CAT(::testing::internal::AdjustConstness_,                 \
+                        GMOCK_PP_IF(_Constness, const, ))(this)                \
+        ->gmock_##_MethodName(GMOCK_PP_REPEAT(                                 \
+            GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N));               \
+  }                                                                            \
+  mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)>        \
+      GMOCK_MOCKER_(_N, _Constness, _MethodName)
+
+#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__
+
+// Five Valid modifiers.
+#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \
+  GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))
+
+#define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \
+  GMOCK_PP_HAS_COMMA(                       \
+      GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple))
+
+#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \
+  GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple))
+
+#define GMOCK_INTERNAL_HAS_NOEXCEPT(_Tuple) \
+  GMOCK_PP_HAS_COMMA(                       \
+      GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_NOEXCEPT, ~, _Tuple))
+
+#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \
+  GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple)
+
+#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem)            \
+  static_assert(                                                          \
+      (GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) +    \
+       GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \
+       GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) +    \
+       GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \
+       GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1,                           \
+      GMOCK_PP_STRINGIZE(                                                 \
+          _elem) " cannot be recognized as a valid specification modifier.");
+
+// Modifiers implementation.
+#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \
+  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem)
+
+#define GMOCK_INTERNAL_DETECT_CONST_I_const ,
+
+#define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \
+  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem)
+
+#define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override ,
+
+#define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \
+  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem)
+
+#define GMOCK_INTERNAL_DETECT_FINAL_I_final ,
+
+// TODO(iserna): Maybe noexcept should accept an argument here as well.
+#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \
+  GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem)
+
+#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept ,
+
+#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem)           \
+  GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem),                 \
+              GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \
+  (_elem)
+
+// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and
+// GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows
+// maybe they can be simplified somehow.
+#define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \
+  GMOCK_INTERNAL_IS_CALLTYPE_I(          \
+      GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
+#define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg)
+
+#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \
+  GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(          \
+      GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
+#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \
+  GMOCK_PP_CAT(GMOCK_PP_IDENTITY, _arg)
+
+#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype
+
+#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)                         \
+  GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), GMOCK_PP_REMOVE_PARENS, \
+              GMOCK_PP_IDENTITY)                                      \
+  (_Ret)(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))
+
+#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem)                          \
+  GMOCK_PP_COMMA_IF(_i)                                                \
+  GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \
+              GMOCK_PP_IDENTITY)                                       \
+  (_elem)
+
+#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _)        \
+  GMOCK_PP_COMMA_IF(_i)                                    \
+  GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i),         \
+                       GMOCK_PP_REMOVE_PARENS(_Signature)) \
+  gmock_a##_i
+
+#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _)                       \
+  GMOCK_PP_COMMA_IF(_i)                                                     \
+  ::std::forward<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i),           \
+                                      GMOCK_PP_REMOVE_PARENS(_Signature))>( \
+      gmock_a##_i)
+
+#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _)    \
+  GMOCK_PP_COMMA_IF(_i)                                        \
+  GMOCK_INTERNAL_MATCHER_O(typename, GMOCK_PP_INC(_i),         \
+                           GMOCK_PP_REMOVE_PARENS(_Signature)) \
+  gmock_a##_i
+
+#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \
+  GMOCK_PP_COMMA_IF(_i)                             \
+  gmock_a##_i
+
+#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _)    \
+  GMOCK_PP_COMMA_IF(_i)                                         \
+  ::testing::A<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
+                                    GMOCK_PP_REMOVE_PARENS(_Signature))>()
+
+#define GMOCK_INTERNAL_ARG_O(_tn, _i, ...) GMOCK_ARG_(_tn, _i, __VA_ARGS__)
+
+#define GMOCK_INTERNAL_MATCHER_O(_tn, _i, ...) \
+  GMOCK_MATCHER_(_tn, _i, __VA_ARGS__)
+
+#endif  // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_
+// This file was GENERATED by command:
+//     pump.py gmock-generated-actions.h.pump
+// DO NOT EDIT BY HAND!!!
+
+// Copyright 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.
+
 
 // Google Mock - a framework for writing C++ mock classes.
 //
 // This file implements some commonly used variadic actions.
 
+// GOOGLETEST_CM0002 DO NOT DELETE
+
 #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
 #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
 
+#include <memory>
+#include <utility>
+
 
 namespace testing {
 namespace internal {
 
-// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
-// function or method with the unpacked values, where F is a function
-// type that takes N arguments.
-template <typename Result, typename ArgumentTuple>
-class InvokeHelper;
-
-template <typename R>
-class InvokeHelper<R, ::testing::tuple<> > {
- public:
-  template <typename Function>
-  static R Invoke(Function function, const ::testing::tuple<>&) {
-           return function();
-  }
-
-  template <class Class, typename MethodPtr>
-  static R InvokeMethod(Class* obj_ptr,
-                        MethodPtr method_ptr,
-                        const ::testing::tuple<>&) {
-           return (obj_ptr->*method_ptr)();
-  }
-};
-
-template <typename R, typename A1>
-class InvokeHelper<R, ::testing::tuple<A1> > {
- public:
-  template <typename Function>
-  static R Invoke(Function function, const ::testing::tuple<A1>& args) {
-           return function(get<0>(args));
-  }
-
-  template <class Class, typename MethodPtr>
-  static R InvokeMethod(Class* obj_ptr,
-                        MethodPtr method_ptr,
-                        const ::testing::tuple<A1>& args) {
-           return (obj_ptr->*method_ptr)(get<0>(args));
-  }
-};
-
-template <typename R, typename A1, typename A2>
-class InvokeHelper<R, ::testing::tuple<A1, A2> > {
- public:
-  template <typename Function>
-  static R Invoke(Function function, const ::testing::tuple<A1, A2>& args) {
-           return function(get<0>(args), get<1>(args));
-  }
-
-  template <class Class, typename MethodPtr>
-  static R InvokeMethod(Class* obj_ptr,
-                        MethodPtr method_ptr,
-                        const ::testing::tuple<A1, A2>& args) {
-           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3> > {
- public:
-  template <typename Function>
-  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3>& args) {
-           return function(get<0>(args), get<1>(args), get<2>(args));
-  }
-
-  template <class Class, typename MethodPtr>
-  static R InvokeMethod(Class* obj_ptr,
-                        MethodPtr method_ptr,
-                        const ::testing::tuple<A1, A2, A3>& args) {
-           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
-               get<2>(args));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4> > {
- public:
-  template <typename Function>
-  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3,
-      A4>& args) {
-           return function(get<0>(args), get<1>(args), get<2>(args),
-               get<3>(args));
-  }
-
-  template <class Class, typename MethodPtr>
-  static R InvokeMethod(Class* obj_ptr,
-                        MethodPtr method_ptr,
-                        const ::testing::tuple<A1, A2, A3, A4>& args) {
-           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
-               get<2>(args), get<3>(args));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5> > {
- public:
-  template <typename Function>
-  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4,
-      A5>& args) {
-           return function(get<0>(args), get<1>(args), get<2>(args),
-               get<3>(args), get<4>(args));
-  }
-
-  template <class Class, typename MethodPtr>
-  static R InvokeMethod(Class* obj_ptr,
-                        MethodPtr method_ptr,
-                        const ::testing::tuple<A1, A2, A3, A4, A5>& args) {
-           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
-               get<2>(args), get<3>(args), get<4>(args));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6> > {
- public:
-  template <typename Function>
-  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
-      A6>& args) {
-           return function(get<0>(args), get<1>(args), get<2>(args),
-               get<3>(args), get<4>(args), get<5>(args));
-  }
-
-  template <class Class, typename MethodPtr>
-  static R InvokeMethod(Class* obj_ptr,
-                        MethodPtr method_ptr,
-                        const ::testing::tuple<A1, A2, A3, A4, A5, A6>& args) {
-           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
-               get<2>(args), get<3>(args), get<4>(args), get<5>(args));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6, typename A7>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > {
- public:
-  template <typename Function>
-  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
-      A6, A7>& args) {
-           return function(get<0>(args), get<1>(args), get<2>(args),
-               get<3>(args), get<4>(args), get<5>(args), get<6>(args));
-  }
-
-  template <class Class, typename MethodPtr>
-  static R InvokeMethod(Class* obj_ptr,
-                        MethodPtr method_ptr,
-                        const ::testing::tuple<A1, A2, A3, A4, A5, A6,
-                            A7>& args) {
-           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
-               get<2>(args), get<3>(args), get<4>(args), get<5>(args),
-               get<6>(args));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6, typename A7, typename A8>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
- public:
-  template <typename Function>
-  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
-      A6, A7, A8>& args) {
-           return function(get<0>(args), get<1>(args), get<2>(args),
-               get<3>(args), get<4>(args), get<5>(args), get<6>(args),
-               get<7>(args));
-  }
-
-  template <class Class, typename MethodPtr>
-  static R InvokeMethod(Class* obj_ptr,
-                        MethodPtr method_ptr,
-                        const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7,
-                            A8>& args) {
-           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
-               get<2>(args), get<3>(args), get<4>(args), get<5>(args),
-               get<6>(args), get<7>(args));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6, typename A7, typename A8, typename A9>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
- public:
-  template <typename Function>
-  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
-      A6, A7, A8, A9>& args) {
-           return function(get<0>(args), get<1>(args), get<2>(args),
-               get<3>(args), get<4>(args), get<5>(args), get<6>(args),
-               get<7>(args), get<8>(args));
-  }
-
-  template <class Class, typename MethodPtr>
-  static R InvokeMethod(Class* obj_ptr,
-                        MethodPtr method_ptr,
-                        const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8,
-                            A9>& args) {
-           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
-               get<2>(args), get<3>(args), get<4>(args), get<5>(args),
-               get<6>(args), get<7>(args), get<8>(args));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6, typename A7, typename A8, typename A9,
-    typename A10>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
-    A10> > {
- public:
-  template <typename Function>
-  static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
-      A6, A7, A8, A9, A10>& args) {
-           return function(get<0>(args), get<1>(args), get<2>(args),
-               get<3>(args), get<4>(args), get<5>(args), get<6>(args),
-               get<7>(args), get<8>(args), get<9>(args));
-  }
-
-  template <class Class, typename MethodPtr>
-  static R InvokeMethod(Class* obj_ptr,
-                        MethodPtr method_ptr,
-                        const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8,
-                            A9, A10>& args) {
-           return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
-               get<2>(args), get<3>(args), get<4>(args), get<5>(args),
-               get<6>(args), get<7>(args), get<8>(args), get<9>(args));
-  }
-};
-
-// An INTERNAL macro for extracting the type of a tuple field.  It's
-// subject to change without notice - DO NOT USE IN USER CODE!
-#define GMOCK_FIELD_(Tuple, N) \
-    typename ::testing::tuple_element<N, Tuple>::type
-
-// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
-// type of an n-ary function whose i-th (1-based) argument type is the
-// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
-// type, and whose return type is Result.  For example,
-//   SelectArgs<int, ::testing::tuple<bool, char, double, long>, 0, 3>::type
-// is int(bool, long).
-//
-// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
-// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
-// For example,
-//   SelectArgs<int, tuple<bool, char, double>, 2, 0>::Select(
-//       ::testing::make_tuple(true, 'a', 2.5))
-// returns tuple (2.5, true).
-//
-// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
-// in the range [0, 10].  Duplicates are allowed and they don't have
-// to be in an ascending or descending order.
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
-    int k4, int k5, int k6, int k7, int k8, int k9, int k10>
-class SelectArgs {
- public:
-  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
-      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
-      GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
-      GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7),
-      GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9),
-      GMOCK_FIELD_(ArgumentTuple, k10));
-  typedef typename Function<type>::ArgumentTuple SelectedArgs;
-  static SelectedArgs Select(const ArgumentTuple& args) {
-    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
-        get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args),
-        get<k8>(args), get<k9>(args), get<k10>(args));
-  }
-};
-
-template <typename Result, typename ArgumentTuple>
-class SelectArgs<Result, ArgumentTuple,
-                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
- public:
-  typedef Result type();
-  typedef typename Function<type>::ArgumentTuple SelectedArgs;
-  static SelectedArgs Select(const ArgumentTuple& /* args */) {
-    return SelectedArgs();
-  }
-};
-
-template <typename Result, typename ArgumentTuple, int k1>
-class SelectArgs<Result, ArgumentTuple,
-                 k1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
- public:
-  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1));
-  typedef typename Function<type>::ArgumentTuple SelectedArgs;
-  static SelectedArgs Select(const ArgumentTuple& args) {
-    return SelectedArgs(get<k1>(args));
-  }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2>
-class SelectArgs<Result, ArgumentTuple,
-                 k1, k2, -1, -1, -1, -1, -1, -1, -1, -1> {
- public:
-  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
-      GMOCK_FIELD_(ArgumentTuple, k2));
-  typedef typename Function<type>::ArgumentTuple SelectedArgs;
-  static SelectedArgs Select(const ArgumentTuple& args) {
-    return SelectedArgs(get<k1>(args), get<k2>(args));
-  }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3>
-class SelectArgs<Result, ArgumentTuple,
-                 k1, k2, k3, -1, -1, -1, -1, -1, -1, -1> {
- public:
-  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
-      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3));
-  typedef typename Function<type>::ArgumentTuple SelectedArgs;
-  static SelectedArgs Select(const ArgumentTuple& args) {
-    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args));
-  }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
-    int k4>
-class SelectArgs<Result, ArgumentTuple,
-                 k1, k2, k3, k4, -1, -1, -1, -1, -1, -1> {
- public:
-  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
-      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
-      GMOCK_FIELD_(ArgumentTuple, k4));
-  typedef typename Function<type>::ArgumentTuple SelectedArgs;
-  static SelectedArgs Select(const ArgumentTuple& args) {
-    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
-        get<k4>(args));
-  }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
-    int k4, int k5>
-class SelectArgs<Result, ArgumentTuple,
-                 k1, k2, k3, k4, k5, -1, -1, -1, -1, -1> {
- public:
-  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
-      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
-      GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5));
-  typedef typename Function<type>::ArgumentTuple SelectedArgs;
-  static SelectedArgs Select(const ArgumentTuple& args) {
-    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
-        get<k4>(args), get<k5>(args));
-  }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
-    int k4, int k5, int k6>
-class SelectArgs<Result, ArgumentTuple,
-                 k1, k2, k3, k4, k5, k6, -1, -1, -1, -1> {
- public:
-  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
-      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
-      GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
-      GMOCK_FIELD_(ArgumentTuple, k6));
-  typedef typename Function<type>::ArgumentTuple SelectedArgs;
-  static SelectedArgs Select(const ArgumentTuple& args) {
-    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
-        get<k4>(args), get<k5>(args), get<k6>(args));
-  }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
-    int k4, int k5, int k6, int k7>
-class SelectArgs<Result, ArgumentTuple,
-                 k1, k2, k3, k4, k5, k6, k7, -1, -1, -1> {
- public:
-  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
-      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
-      GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
-      GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7));
-  typedef typename Function<type>::ArgumentTuple SelectedArgs;
-  static SelectedArgs Select(const ArgumentTuple& args) {
-    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
-        get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args));
-  }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
-    int k4, int k5, int k6, int k7, int k8>
-class SelectArgs<Result, ArgumentTuple,
-                 k1, k2, k3, k4, k5, k6, k7, k8, -1, -1> {
- public:
-  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
-      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
-      GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
-      GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7),
-      GMOCK_FIELD_(ArgumentTuple, k8));
-  typedef typename Function<type>::ArgumentTuple SelectedArgs;
-  static SelectedArgs Select(const ArgumentTuple& args) {
-    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
-        get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args),
-        get<k8>(args));
-  }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
-    int k4, int k5, int k6, int k7, int k8, int k9>
-class SelectArgs<Result, ArgumentTuple,
-                 k1, k2, k3, k4, k5, k6, k7, k8, k9, -1> {
- public:
-  typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
-      GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
-      GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
-      GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7),
-      GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9));
-  typedef typename Function<type>::ArgumentTuple SelectedArgs;
-  static SelectedArgs Select(const ArgumentTuple& args) {
-    return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
-        get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args),
-        get<k8>(args), get<k9>(args));
-  }
-};
-
-#undef GMOCK_FIELD_
-
-// Implements the WithArgs action.
-template <typename InnerAction, int k1 = -1, int k2 = -1, int k3 = -1,
-    int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1,
-    int k9 = -1, int k10 = -1>
-class WithArgsAction {
- public:
-  explicit WithArgsAction(const InnerAction& action) : action_(action) {}
-
-  template <typename F>
-  operator Action<F>() const { return MakeAction(new Impl<F>(action_)); }
-
- private:
-  template <typename F>
-  class Impl : public ActionInterface<F> {
-   public:
-    typedef typename Function<F>::Result Result;
-    typedef typename Function<F>::ArgumentTuple ArgumentTuple;
-
-    explicit Impl(const InnerAction& action) : action_(action) {}
-
-    virtual Result Perform(const ArgumentTuple& args) {
-      return action_.Perform(SelectArgs<Result, ArgumentTuple, k1, k2, k3, k4,
-          k5, k6, k7, k8, k9, k10>::Select(args));
-    }
-
-   private:
-    typedef typename SelectArgs<Result, ArgumentTuple,
-        k1, k2, k3, k4, k5, k6, k7, k8, k9, k10>::type InnerFunctionType;
-
-    Action<InnerFunctionType> action_;
-  };
-
-  const InnerAction action_;
-
-  GTEST_DISALLOW_ASSIGN_(WithArgsAction);
-};
-
 // A macro from the ACTION* family (defined later in this file)
 // defines an action that can be used in a mock function.  Typically,
 // these actions only care about a subset of the arguments of the mock
@@ -2835,7 +10024,7 @@
 template <typename Result, class Impl>
 class ActionHelper {
  public:
-  static Result Perform(Impl* impl, const ::testing::tuple<>& args) {
+  static Result Perform(Impl* impl, const ::std::tuple<>& args) {
     return impl->template gmock_PerformImpl<>(args, ExcessiveArg(),
         ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
         ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
@@ -2843,266 +10032,100 @@
   }
 
   template <typename A0>
-  static Result Perform(Impl* impl, const ::testing::tuple<A0>& args) {
-    return impl->template gmock_PerformImpl<A0>(args, get<0>(args),
+  static Result Perform(Impl* impl, const ::std::tuple<A0>& args) {
+    return impl->template gmock_PerformImpl<A0>(args, std::get<0>(args),
         ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
         ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
         ExcessiveArg());
   }
 
   template <typename A0, typename A1>
-  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1>& args) {
-    return impl->template gmock_PerformImpl<A0, A1>(args, get<0>(args),
-        get<1>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
+  static Result Perform(Impl* impl, const ::std::tuple<A0, A1>& args) {
+    return impl->template gmock_PerformImpl<A0, A1>(args, std::get<0>(args),
+        std::get<1>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
         ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
         ExcessiveArg());
   }
 
   template <typename A0, typename A1, typename A2>
-  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2>& args) {
-    return impl->template gmock_PerformImpl<A0, A1, A2>(args, get<0>(args),
-        get<1>(args), get<2>(args), ExcessiveArg(), ExcessiveArg(),
+  static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2>& args) {
+    return impl->template gmock_PerformImpl<A0, A1, A2>(args,
+        std::get<0>(args), std::get<1>(args), std::get<2>(args),
         ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
-        ExcessiveArg());
+        ExcessiveArg(), ExcessiveArg(), ExcessiveArg());
   }
 
   template <typename A0, typename A1, typename A2, typename A3>
-  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2,
-      A3>& args) {
-    return impl->template gmock_PerformImpl<A0, A1, A2, A3>(args, get<0>(args),
-        get<1>(args), get<2>(args), get<3>(args), ExcessiveArg(),
-        ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
-        ExcessiveArg());
+  static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3>& args) {
+    return impl->template gmock_PerformImpl<A0, A1, A2, A3>(args,
+        std::get<0>(args), std::get<1>(args), std::get<2>(args),
+        std::get<3>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
+        ExcessiveArg(), ExcessiveArg(), ExcessiveArg());
   }
 
   template <typename A0, typename A1, typename A2, typename A3, typename A4>
-  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3,
+  static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3,
       A4>& args) {
     return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4>(args,
-        get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args),
-        ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
-        ExcessiveArg());
+        std::get<0>(args), std::get<1>(args), std::get<2>(args),
+        std::get<3>(args), std::get<4>(args), ExcessiveArg(), ExcessiveArg(),
+        ExcessiveArg(), ExcessiveArg(), ExcessiveArg());
   }
 
   template <typename A0, typename A1, typename A2, typename A3, typename A4,
       typename A5>
-  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
+  static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4,
       A5>& args) {
     return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5>(args,
-        get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args),
-        get<5>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
-        ExcessiveArg());
+        std::get<0>(args), std::get<1>(args), std::get<2>(args),
+        std::get<3>(args), std::get<4>(args), std::get<5>(args),
+        ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg());
   }
 
   template <typename A0, typename A1, typename A2, typename A3, typename A4,
       typename A5, typename A6>
-  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
-      A5, A6>& args) {
+  static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4, A5,
+      A6>& args) {
     return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6>(args,
-        get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args),
-        get<5>(args), get<6>(args), ExcessiveArg(), ExcessiveArg(),
-        ExcessiveArg());
+        std::get<0>(args), std::get<1>(args), std::get<2>(args),
+        std::get<3>(args), std::get<4>(args), std::get<5>(args),
+        std::get<6>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg());
   }
 
   template <typename A0, typename A1, typename A2, typename A3, typename A4,
       typename A5, typename A6, typename A7>
-  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
-      A5, A6, A7>& args) {
+  static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4, A5,
+      A6, A7>& args) {
     return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6,
-        A7>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args),
-        get<4>(args), get<5>(args), get<6>(args), get<7>(args), ExcessiveArg(),
-        ExcessiveArg());
+        A7>(args, std::get<0>(args), std::get<1>(args), std::get<2>(args),
+        std::get<3>(args), std::get<4>(args), std::get<5>(args),
+        std::get<6>(args), std::get<7>(args), ExcessiveArg(), ExcessiveArg());
   }
 
   template <typename A0, typename A1, typename A2, typename A3, typename A4,
       typename A5, typename A6, typename A7, typename A8>
-  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
-      A5, A6, A7, A8>& args) {
+  static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4, A5,
+      A6, A7, A8>& args) {
     return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, A7,
-        A8>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args),
-        get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args),
+        A8>(args, std::get<0>(args), std::get<1>(args), std::get<2>(args),
+        std::get<3>(args), std::get<4>(args), std::get<5>(args),
+        std::get<6>(args), std::get<7>(args), std::get<8>(args),
         ExcessiveArg());
   }
 
   template <typename A0, typename A1, typename A2, typename A3, typename A4,
       typename A5, typename A6, typename A7, typename A8, typename A9>
-  static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
-      A5, A6, A7, A8, A9>& args) {
+  static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4, A5,
+      A6, A7, A8, A9>& args) {
     return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, A7, A8,
-        A9>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args),
-        get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args),
-        get<9>(args));
+        A9>(args, std::get<0>(args), std::get<1>(args), std::get<2>(args),
+        std::get<3>(args), std::get<4>(args), std::get<5>(args),
+        std::get<6>(args), std::get<7>(args), std::get<8>(args),
+        std::get<9>(args));
   }
 };
 
 }  // namespace internal
-
-// Various overloads for Invoke().
-
-// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
-// the selected arguments of the mock function to an_action and
-// performs it.  It serves as an adaptor between actions with
-// different argument lists.  C++ doesn't support default arguments for
-// function templates, so we have to overload it.
-template <int k1, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1>
-WithArgs(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction, k1>(action);
-}
-
-template <int k1, int k2, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2>
-WithArgs(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction, k1, k2>(action);
-}
-
-template <int k1, int k2, int k3, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3>
-WithArgs(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction, k1, k2, k3>(action);
-}
-
-template <int k1, int k2, int k3, int k4, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4>
-WithArgs(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4>(action);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5>
-WithArgs(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5>(action);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6>
-WithArgs(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6>(action);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7,
-    typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7>
-WithArgs(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6,
-      k7>(action);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
-    typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8>
-WithArgs(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7,
-      k8>(action);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
-    int k9, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8, k9>
-WithArgs(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
-      k9>(action);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
-    int k9, int k10, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
-    k9, k10>
-WithArgs(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
-      k9, k10>(action);
-}
-
-// Creates an action that does actions a1, a2, ..., sequentially in
-// each invocation.
-template <typename Action1, typename Action2>
-inline internal::DoBothAction<Action1, Action2>
-DoAll(Action1 a1, Action2 a2) {
-  return internal::DoBothAction<Action1, Action2>(a1, a2);
-}
-
-template <typename Action1, typename Action2, typename Action3>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
-    Action3> >
-DoAll(Action1 a1, Action2 a2, Action3 a3) {
-  return DoAll(a1, DoAll(a2, a3));
-}
-
-template <typename Action1, typename Action2, typename Action3,
-    typename Action4>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
-    internal::DoBothAction<Action3, Action4> > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4) {
-  return DoAll(a1, DoAll(a2, a3, a4));
-}
-
-template <typename Action1, typename Action2, typename Action3,
-    typename Action4, typename Action5>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
-    internal::DoBothAction<Action3, internal::DoBothAction<Action4,
-    Action5> > > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5) {
-  return DoAll(a1, DoAll(a2, a3, a4, a5));
-}
-
-template <typename Action1, typename Action2, typename Action3,
-    typename Action4, typename Action5, typename Action6>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
-    internal::DoBothAction<Action3, internal::DoBothAction<Action4,
-    internal::DoBothAction<Action5, Action6> > > > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6) {
-  return DoAll(a1, DoAll(a2, a3, a4, a5, a6));
-}
-
-template <typename Action1, typename Action2, typename Action3,
-    typename Action4, typename Action5, typename Action6, typename Action7>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
-    internal::DoBothAction<Action3, internal::DoBothAction<Action4,
-    internal::DoBothAction<Action5, internal::DoBothAction<Action6,
-    Action7> > > > > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
-    Action7 a7) {
-  return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7));
-}
-
-template <typename Action1, typename Action2, typename Action3,
-    typename Action4, typename Action5, typename Action6, typename Action7,
-    typename Action8>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
-    internal::DoBothAction<Action3, internal::DoBothAction<Action4,
-    internal::DoBothAction<Action5, internal::DoBothAction<Action6,
-    internal::DoBothAction<Action7, Action8> > > > > > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
-    Action7 a7, Action8 a8) {
-  return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8));
-}
-
-template <typename Action1, typename Action2, typename Action3,
-    typename Action4, typename Action5, typename Action6, typename Action7,
-    typename Action8, typename Action9>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
-    internal::DoBothAction<Action3, internal::DoBothAction<Action4,
-    internal::DoBothAction<Action5, internal::DoBothAction<Action6,
-    internal::DoBothAction<Action7, internal::DoBothAction<Action8,
-    Action9> > > > > > > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
-    Action7 a7, Action8 a8, Action9 a9) {
-  return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9));
-}
-
-template <typename Action1, typename Action2, typename Action3,
-    typename Action4, typename Action5, typename Action6, typename Action7,
-    typename Action8, typename Action9, typename Action10>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
-    internal::DoBothAction<Action3, internal::DoBothAction<Action4,
-    internal::DoBothAction<Action5, internal::DoBothAction<Action6,
-    internal::DoBothAction<Action7, internal::DoBothAction<Action8,
-    internal::DoBothAction<Action9, Action10> > > > > > > > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
-    Action7 a7, Action8 a8, Action9 a9, Action10 a10) {
-  return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9, a10));
-}
-
 }  // namespace testing
 
 // The ACTION* family of macros can be used in a namespace scope to
@@ -3198,8 +10221,8 @@
 //
 // MORE INFORMATION:
 //
-// To learn more about using these macros, please search for 'ACTION'
-// on http://code.google.com/p/googlemock/wiki/CookBook.
+// To learn more about using these macros, please search for 'ACTION' on
+// https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md
 
 // An internal macro needed for implementing ACTION*().
 #define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
@@ -3239,7 +10262,7 @@
 //   ACTION_TEMPLATE(DuplicateArg,
 //                   HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
 //                   AND_1_VALUE_PARAMS(output)) {
-//     *output = T(::testing::get<k>(args));
+//     *output = T(::std::get<k>(args));
 //   }
 //   ...
 //     int n;
@@ -3397,52 +10420,67 @@
 #define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\
     ()
 #define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\
-    (p0##_type gmock_p0) : p0(gmock_p0)
+    (p0##_type gmock_p0) : p0(::std::move(gmock_p0))
 #define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\
-    (p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), p1(gmock_p1)
+    (p0##_type gmock_p0, p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1))
 #define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\
     (p0##_type gmock_p0, p1##_type gmock_p1, \
-        p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2)
+        p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2))
 #define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\
     (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
-        p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-        p3(gmock_p3)
+        p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3))
 #define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\
     (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
-        p3##_type gmock_p3, p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), \
-        p2(gmock_p2), p3(gmock_p3), p4(gmock_p4)
+        p3##_type gmock_p3, p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4))
 #define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\
     (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
         p3##_type gmock_p3, p4##_type gmock_p4, \
-        p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5)
+        p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+        p5(::std::move(gmock_p5))
 #define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\
     (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
         p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
-        p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6)
+        p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+        p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6))
 #define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\
     (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
         p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
-        p6##_type gmock_p6, p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), \
-        p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
-        p7(gmock_p7)
+        p6##_type gmock_p6, p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+        p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
+        p7(::std::move(gmock_p7))
 #define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
     p7, p8)\
     (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
         p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
         p6##_type gmock_p6, p7##_type gmock_p7, \
-        p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
-        p8(gmock_p8)
+        p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+        p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
+        p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8))
 #define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
     p7, p8, p9)\
     (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
         p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
         p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
-        p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
-        p8(gmock_p8), p9(gmock_p9)
+        p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+        p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
+        p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \
+        p9(::std::move(gmock_p9))
 
 // Declares the fields for storing the value parameters.
 #define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS()
@@ -3678,7 +10716,8 @@
   template <typename p0##_type>\
   class name##ActionP {\
    public:\
-    explicit name##ActionP(p0##_type gmock_p0) : p0(gmock_p0) {}\
+    explicit name##ActionP(p0##_type gmock_p0) : \
+        p0(::std::forward<p0##_type>(gmock_p0)) {}\
     template <typename F>\
     class gmock_Impl : public ::testing::ActionInterface<F> {\
      public:\
@@ -3686,7 +10725,8 @@
       typedef typename ::testing::internal::Function<F>::Result return_type;\
       typedef typename ::testing::internal::Function<F>::ArgumentTuple\
           args_type;\
-      explicit gmock_Impl(p0##_type gmock_p0) : p0(gmock_p0) {}\
+      explicit gmock_Impl(p0##_type gmock_p0) : \
+          p0(::std::forward<p0##_type>(gmock_p0)) {}\
       virtual return_type Perform(const args_type& args) {\
         return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
             Perform(this, args);\
@@ -3728,8 +10768,9 @@
   template <typename p0##_type, typename p1##_type>\
   class name##ActionP2 {\
    public:\
-    name##ActionP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
-        p1(gmock_p1) {}\
+    name##ActionP2(p0##_type gmock_p0, \
+        p1##_type gmock_p1) : p0(::std::forward<p0##_type>(gmock_p0)), \
+        p1(::std::forward<p1##_type>(gmock_p1)) {}\
     template <typename F>\
     class gmock_Impl : public ::testing::ActionInterface<F> {\
      public:\
@@ -3737,8 +10778,9 @@
       typedef typename ::testing::internal::Function<F>::Result return_type;\
       typedef typename ::testing::internal::Function<F>::ArgumentTuple\
           args_type;\
-      gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
-          p1(gmock_p1) {}\
+      gmock_Impl(p0##_type gmock_p0, \
+          p1##_type gmock_p1) : p0(::std::forward<p0##_type>(gmock_p0)), \
+          p1(::std::forward<p1##_type>(gmock_p1)) {}\
       virtual return_type Perform(const args_type& args) {\
         return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
             Perform(this, args);\
@@ -3784,7 +10826,9 @@
   class name##ActionP3 {\
    public:\
     name##ActionP3(p0##_type gmock_p0, p1##_type gmock_p1, \
-        p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\
+        p2##_type gmock_p2) : p0(::std::forward<p0##_type>(gmock_p0)), \
+        p1(::std::forward<p1##_type>(gmock_p1)), \
+        p2(::std::forward<p2##_type>(gmock_p2)) {}\
     template <typename F>\
     class gmock_Impl : public ::testing::ActionInterface<F> {\
      public:\
@@ -3793,7 +10837,9 @@
       typedef typename ::testing::internal::Function<F>::ArgumentTuple\
           args_type;\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \
-          p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\
+          p2##_type gmock_p2) : p0(::std::forward<p0##_type>(gmock_p0)), \
+          p1(::std::forward<p1##_type>(gmock_p1)), \
+          p2(::std::forward<p2##_type>(gmock_p2)) {}\
       virtual return_type Perform(const args_type& args) {\
         return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
             Perform(this, args);\
@@ -3843,8 +10889,11 @@
   class name##ActionP4 {\
    public:\
     name##ActionP4(p0##_type gmock_p0, p1##_type gmock_p1, \
-        p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \
-        p2(gmock_p2), p3(gmock_p3) {}\
+        p2##_type gmock_p2, \
+        p3##_type gmock_p3) : p0(::std::forward<p0##_type>(gmock_p0)), \
+        p1(::std::forward<p1##_type>(gmock_p1)), \
+        p2(::std::forward<p2##_type>(gmock_p2)), \
+        p3(::std::forward<p3##_type>(gmock_p3)) {}\
     template <typename F>\
     class gmock_Impl : public ::testing::ActionInterface<F> {\
      public:\
@@ -3853,8 +10902,10 @@
       typedef typename ::testing::internal::Function<F>::ArgumentTuple\
           args_type;\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
-          p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-          p3(gmock_p3) {}\
+          p3##_type gmock_p3) : p0(::std::forward<p0##_type>(gmock_p0)), \
+          p1(::std::forward<p1##_type>(gmock_p1)), \
+          p2(::std::forward<p2##_type>(gmock_p2)), \
+          p3(::std::forward<p3##_type>(gmock_p3)) {}\
       virtual return_type Perform(const args_type& args) {\
         return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
             Perform(this, args);\
@@ -3911,8 +10962,11 @@
    public:\
     name##ActionP5(p0##_type gmock_p0, p1##_type gmock_p1, \
         p2##_type gmock_p2, p3##_type gmock_p3, \
-        p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-        p3(gmock_p3), p4(gmock_p4) {}\
+        p4##_type gmock_p4) : p0(::std::forward<p0##_type>(gmock_p0)), \
+        p1(::std::forward<p1##_type>(gmock_p1)), \
+        p2(::std::forward<p2##_type>(gmock_p2)), \
+        p3(::std::forward<p3##_type>(gmock_p3)), \
+        p4(::std::forward<p4##_type>(gmock_p4)) {}\
     template <typename F>\
     class gmock_Impl : public ::testing::ActionInterface<F> {\
      public:\
@@ -3921,8 +10975,12 @@
       typedef typename ::testing::internal::Function<F>::ArgumentTuple\
           args_type;\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
-          p3##_type gmock_p3, p4##_type gmock_p4) : p0(gmock_p0), \
-          p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4) {}\
+          p3##_type gmock_p3, \
+          p4##_type gmock_p4) : p0(::std::forward<p0##_type>(gmock_p0)), \
+          p1(::std::forward<p1##_type>(gmock_p1)), \
+          p2(::std::forward<p2##_type>(gmock_p2)), \
+          p3(::std::forward<p3##_type>(gmock_p3)), \
+          p4(::std::forward<p4##_type>(gmock_p4)) {}\
       virtual return_type Perform(const args_type& args) {\
         return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
             Perform(this, args);\
@@ -3981,8 +11039,12 @@
    public:\
     name##ActionP6(p0##_type gmock_p0, p1##_type gmock_p1, \
         p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
-        p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\
+        p5##_type gmock_p5) : p0(::std::forward<p0##_type>(gmock_p0)), \
+        p1(::std::forward<p1##_type>(gmock_p1)), \
+        p2(::std::forward<p2##_type>(gmock_p2)), \
+        p3(::std::forward<p3##_type>(gmock_p3)), \
+        p4(::std::forward<p4##_type>(gmock_p4)), \
+        p5(::std::forward<p5##_type>(gmock_p5)) {}\
     template <typename F>\
     class gmock_Impl : public ::testing::ActionInterface<F> {\
      public:\
@@ -3992,8 +11054,12 @@
           args_type;\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
           p3##_type gmock_p3, p4##_type gmock_p4, \
-          p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-          p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\
+          p5##_type gmock_p5) : p0(::std::forward<p0##_type>(gmock_p0)), \
+          p1(::std::forward<p1##_type>(gmock_p1)), \
+          p2(::std::forward<p2##_type>(gmock_p2)), \
+          p3(::std::forward<p3##_type>(gmock_p3)), \
+          p4(::std::forward<p4##_type>(gmock_p4)), \
+          p5(::std::forward<p5##_type>(gmock_p5)) {}\
       virtual return_type Perform(const args_type& args) {\
         return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
             Perform(this, args);\
@@ -4055,9 +11121,14 @@
    public:\
     name##ActionP7(p0##_type gmock_p0, p1##_type gmock_p1, \
         p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
-        p5##_type gmock_p5, p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), \
-        p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \
-        p6(gmock_p6) {}\
+        p5##_type gmock_p5, \
+        p6##_type gmock_p6) : p0(::std::forward<p0##_type>(gmock_p0)), \
+        p1(::std::forward<p1##_type>(gmock_p1)), \
+        p2(::std::forward<p2##_type>(gmock_p2)), \
+        p3(::std::forward<p3##_type>(gmock_p3)), \
+        p4(::std::forward<p4##_type>(gmock_p4)), \
+        p5(::std::forward<p5##_type>(gmock_p5)), \
+        p6(::std::forward<p6##_type>(gmock_p6)) {}\
     template <typename F>\
     class gmock_Impl : public ::testing::ActionInterface<F> {\
      public:\
@@ -4067,8 +11138,13 @@
           args_type;\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
           p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
-          p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-          p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\
+          p6##_type gmock_p6) : p0(::std::forward<p0##_type>(gmock_p0)), \
+          p1(::std::forward<p1##_type>(gmock_p1)), \
+          p2(::std::forward<p2##_type>(gmock_p2)), \
+          p3(::std::forward<p3##_type>(gmock_p3)), \
+          p4(::std::forward<p4##_type>(gmock_p4)), \
+          p5(::std::forward<p5##_type>(gmock_p5)), \
+          p6(::std::forward<p6##_type>(gmock_p6)) {}\
       virtual return_type Perform(const args_type& args) {\
         return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
             Perform(this, args);\
@@ -4137,9 +11213,14 @@
     name##ActionP8(p0##_type gmock_p0, p1##_type gmock_p1, \
         p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
         p5##_type gmock_p5, p6##_type gmock_p6, \
-        p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
-        p7(gmock_p7) {}\
+        p7##_type gmock_p7) : p0(::std::forward<p0##_type>(gmock_p0)), \
+        p1(::std::forward<p1##_type>(gmock_p1)), \
+        p2(::std::forward<p2##_type>(gmock_p2)), \
+        p3(::std::forward<p3##_type>(gmock_p3)), \
+        p4(::std::forward<p4##_type>(gmock_p4)), \
+        p5(::std::forward<p5##_type>(gmock_p5)), \
+        p6(::std::forward<p6##_type>(gmock_p6)), \
+        p7(::std::forward<p7##_type>(gmock_p7)) {}\
     template <typename F>\
     class gmock_Impl : public ::testing::ActionInterface<F> {\
      public:\
@@ -4149,9 +11230,15 @@
           args_type;\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
           p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
-          p6##_type gmock_p6, p7##_type gmock_p7) : p0(gmock_p0), \
-          p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), \
-          p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\
+          p6##_type gmock_p6, \
+          p7##_type gmock_p7) : p0(::std::forward<p0##_type>(gmock_p0)), \
+          p1(::std::forward<p1##_type>(gmock_p1)), \
+          p2(::std::forward<p2##_type>(gmock_p2)), \
+          p3(::std::forward<p3##_type>(gmock_p3)), \
+          p4(::std::forward<p4##_type>(gmock_p4)), \
+          p5(::std::forward<p5##_type>(gmock_p5)), \
+          p6(::std::forward<p6##_type>(gmock_p6)), \
+          p7(::std::forward<p7##_type>(gmock_p7)) {}\
       virtual return_type Perform(const args_type& args) {\
         return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
             Perform(this, args);\
@@ -4224,9 +11311,15 @@
     name##ActionP9(p0##_type gmock_p0, p1##_type gmock_p1, \
         p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
         p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
-        p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
-        p8(gmock_p8) {}\
+        p8##_type gmock_p8) : p0(::std::forward<p0##_type>(gmock_p0)), \
+        p1(::std::forward<p1##_type>(gmock_p1)), \
+        p2(::std::forward<p2##_type>(gmock_p2)), \
+        p3(::std::forward<p3##_type>(gmock_p3)), \
+        p4(::std::forward<p4##_type>(gmock_p4)), \
+        p5(::std::forward<p5##_type>(gmock_p5)), \
+        p6(::std::forward<p6##_type>(gmock_p6)), \
+        p7(::std::forward<p7##_type>(gmock_p7)), \
+        p8(::std::forward<p8##_type>(gmock_p8)) {}\
     template <typename F>\
     class gmock_Impl : public ::testing::ActionInterface<F> {\
      public:\
@@ -4237,9 +11330,15 @@
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
           p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
           p6##_type gmock_p6, p7##_type gmock_p7, \
-          p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-          p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
-          p7(gmock_p7), p8(gmock_p8) {}\
+          p8##_type gmock_p8) : p0(::std::forward<p0##_type>(gmock_p0)), \
+          p1(::std::forward<p1##_type>(gmock_p1)), \
+          p2(::std::forward<p2##_type>(gmock_p2)), \
+          p3(::std::forward<p3##_type>(gmock_p3)), \
+          p4(::std::forward<p4##_type>(gmock_p4)), \
+          p5(::std::forward<p5##_type>(gmock_p5)), \
+          p6(::std::forward<p6##_type>(gmock_p6)), \
+          p7(::std::forward<p7##_type>(gmock_p7)), \
+          p8(::std::forward<p8##_type>(gmock_p8)) {}\
       virtual return_type Perform(const args_type& args) {\
         return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
             Perform(this, args);\
@@ -4316,9 +11415,17 @@
     name##ActionP10(p0##_type gmock_p0, p1##_type gmock_p1, \
         p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
         p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
-        p8##_type gmock_p8, p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), \
-        p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
-        p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\
+        p8##_type gmock_p8, \
+        p9##_type gmock_p9) : p0(::std::forward<p0##_type>(gmock_p0)), \
+        p1(::std::forward<p1##_type>(gmock_p1)), \
+        p2(::std::forward<p2##_type>(gmock_p2)), \
+        p3(::std::forward<p3##_type>(gmock_p3)), \
+        p4(::std::forward<p4##_type>(gmock_p4)), \
+        p5(::std::forward<p5##_type>(gmock_p5)), \
+        p6(::std::forward<p6##_type>(gmock_p6)), \
+        p7(::std::forward<p7##_type>(gmock_p7)), \
+        p8(::std::forward<p8##_type>(gmock_p8)), \
+        p9(::std::forward<p9##_type>(gmock_p9)) {}\
     template <typename F>\
     class gmock_Impl : public ::testing::ActionInterface<F> {\
      public:\
@@ -4329,9 +11436,16 @@
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
           p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
           p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
-          p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-          p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
-          p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\
+          p9##_type gmock_p9) : p0(::std::forward<p0##_type>(gmock_p0)), \
+          p1(::std::forward<p1##_type>(gmock_p1)), \
+          p2(::std::forward<p2##_type>(gmock_p2)), \
+          p3(::std::forward<p3##_type>(gmock_p3)), \
+          p4(::std::forward<p4##_type>(gmock_p4)), \
+          p5(::std::forward<p5##_type>(gmock_p5)), \
+          p6(::std::forward<p6##_type>(gmock_p6)), \
+          p7(::std::forward<p7##_type>(gmock_p7)), \
+          p8(::std::forward<p8##_type>(gmock_p8)), \
+          p9(::std::forward<p9##_type>(gmock_p9)) {}\
       virtual return_type Perform(const args_type& args) {\
         return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
             Perform(this, args);\
@@ -4523,7 +11637,7 @@
   using internal::invoke_argument::InvokeArgumentAdl;
   return InvokeArgumentAdl<return_type>(
       internal::invoke_argument::AdlTag(),
-      ::testing::get<k>(args));
+      ::std::get<k>(args));
 }
 
 ACTION_TEMPLATE(InvokeArgument,
@@ -4532,7 +11646,7 @@
   using internal::invoke_argument::InvokeArgumentAdl;
   return InvokeArgumentAdl<return_type>(
       internal::invoke_argument::AdlTag(),
-      ::testing::get<k>(args), p0);
+      ::std::get<k>(args), p0);
 }
 
 ACTION_TEMPLATE(InvokeArgument,
@@ -4541,7 +11655,7 @@
   using internal::invoke_argument::InvokeArgumentAdl;
   return InvokeArgumentAdl<return_type>(
       internal::invoke_argument::AdlTag(),
-      ::testing::get<k>(args), p0, p1);
+      ::std::get<k>(args), p0, p1);
 }
 
 ACTION_TEMPLATE(InvokeArgument,
@@ -4550,7 +11664,7 @@
   using internal::invoke_argument::InvokeArgumentAdl;
   return InvokeArgumentAdl<return_type>(
       internal::invoke_argument::AdlTag(),
-      ::testing::get<k>(args), p0, p1, p2);
+      ::std::get<k>(args), p0, p1, p2);
 }
 
 ACTION_TEMPLATE(InvokeArgument,
@@ -4559,7 +11673,7 @@
   using internal::invoke_argument::InvokeArgumentAdl;
   return InvokeArgumentAdl<return_type>(
       internal::invoke_argument::AdlTag(),
-      ::testing::get<k>(args), p0, p1, p2, p3);
+      ::std::get<k>(args), p0, p1, p2, p3);
 }
 
 ACTION_TEMPLATE(InvokeArgument,
@@ -4568,7 +11682,7 @@
   using internal::invoke_argument::InvokeArgumentAdl;
   return InvokeArgumentAdl<return_type>(
       internal::invoke_argument::AdlTag(),
-      ::testing::get<k>(args), p0, p1, p2, p3, p4);
+      ::std::get<k>(args), p0, p1, p2, p3, p4);
 }
 
 ACTION_TEMPLATE(InvokeArgument,
@@ -4577,7 +11691,7 @@
   using internal::invoke_argument::InvokeArgumentAdl;
   return InvokeArgumentAdl<return_type>(
       internal::invoke_argument::AdlTag(),
-      ::testing::get<k>(args), p0, p1, p2, p3, p4, p5);
+      ::std::get<k>(args), p0, p1, p2, p3, p4, p5);
 }
 
 ACTION_TEMPLATE(InvokeArgument,
@@ -4586,7 +11700,7 @@
   using internal::invoke_argument::InvokeArgumentAdl;
   return InvokeArgumentAdl<return_type>(
       internal::invoke_argument::AdlTag(),
-      ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6);
+      ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6);
 }
 
 ACTION_TEMPLATE(InvokeArgument,
@@ -4595,7 +11709,7 @@
   using internal::invoke_argument::InvokeArgumentAdl;
   return InvokeArgumentAdl<return_type>(
       internal::invoke_argument::AdlTag(),
-      ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7);
+      ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7);
 }
 
 ACTION_TEMPLATE(InvokeArgument,
@@ -4604,7 +11718,7 @@
   using internal::invoke_argument::InvokeArgumentAdl;
   return InvokeArgumentAdl<return_type>(
       internal::invoke_argument::AdlTag(),
-      ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8);
+      ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8);
 }
 
 ACTION_TEMPLATE(InvokeArgument,
@@ -4613,7 +11727,7 @@
   using internal::invoke_argument::InvokeArgumentAdl;
   return InvokeArgumentAdl<return_type>(
       internal::invoke_argument::AdlTag(),
-      ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
+      ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
 }
 
 // Various overloads for ReturnNew<T>().
@@ -4693,13 +11807,15 @@
 
 }  // namespace testing
 
-// Include any custom actions added by the local installation.
+// Include any custom callback actions added by the local installation.
 // We must include this header at the end to make sure it can use the
 // declarations from this file.
 // This file was GENERATED by command:
 //     pump.py gmock-generated-actions.h.pump
 // DO NOT EDIT BY HAND!!!
 
+// GOOGLETEST_CM0002 DO NOT DELETE
+
 #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
 #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
 
@@ -4707,7769 +11823,6 @@
 
 #endif  // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
 // This file was GENERATED by command:
-//     pump.py gmock-generated-function-mockers.h.pump
-// DO NOT EDIT BY HAND!!!
-
-// Copyright 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: wan@google.com (Zhanyong Wan)
-
-// Google Mock - a framework for writing C++ mock classes.
-//
-// This file implements function mockers of various arities.
-
-#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
-#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
-
-// Copyright 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: wan@google.com (Zhanyong Wan)
-
-// Google Mock - a framework for writing C++ mock classes.
-//
-// This file implements the ON_CALL() and EXPECT_CALL() macros.
-//
-// A user can use the ON_CALL() macro to specify the default action of
-// a mock method.  The syntax is:
-//
-//   ON_CALL(mock_object, Method(argument-matchers))
-//       .With(multi-argument-matcher)
-//       .WillByDefault(action);
-//
-//  where the .With() clause is optional.
-//
-// A user can use the EXPECT_CALL() macro to specify an expectation on
-// a mock method.  The syntax is:
-//
-//   EXPECT_CALL(mock_object, Method(argument-matchers))
-//       .With(multi-argument-matchers)
-//       .Times(cardinality)
-//       .InSequence(sequences)
-//       .After(expectations)
-//       .WillOnce(action)
-//       .WillRepeatedly(action)
-//       .RetiresOnSaturation();
-//
-// where all clauses are optional, and .InSequence()/.After()/
-// .WillOnce() can appear any number of times.
-
-#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
-#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
-
-#include <map>
-#include <set>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#if GTEST_HAS_EXCEPTIONS
-# include <stdexcept>  // NOLINT
-#endif
-
-// Copyright 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: wan@google.com (Zhanyong Wan)
-
-// Google Mock - a framework for writing C++ mock classes.
-//
-// This file implements some commonly used argument matchers.  More
-// matchers can be defined by the user implementing the
-// MatcherInterface<T> interface if necessary.
-
-#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
-#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
-
-#include <math.h>
-#include <algorithm>
-#include <iterator>
-#include <limits>
-#include <ostream>  // NOLINT
-#include <sstream>
-#include <string>
-#include <utility>
-#include <vector>
-
-
-#if GTEST_HAS_STD_INITIALIZER_LIST_
-# include <initializer_list>  // NOLINT -- must be after gtest.h
-#endif
-
-namespace testing {
-
-// To implement a matcher Foo for type T, define:
-//   1. a class FooMatcherImpl that implements the
-//      MatcherInterface<T> interface, and
-//   2. a factory function that creates a Matcher<T> object from a
-//      FooMatcherImpl*.
-//
-// The two-level delegation design makes it possible to allow a user
-// to write "v" instead of "Eq(v)" where a Matcher is expected, which
-// is impossible if we pass matchers by pointers.  It also eases
-// ownership management as Matcher objects can now be copied like
-// plain values.
-
-// MatchResultListener is an abstract class.  Its << operator can be
-// used by a matcher to explain why a value matches or doesn't match.
-//
-// TODO(wan@google.com): add method
-//   bool InterestedInWhy(bool result) const;
-// to indicate whether the listener is interested in why the match
-// result is 'result'.
-class MatchResultListener {
- public:
-  // Creates a listener object with the given underlying ostream.  The
-  // listener does not own the ostream, and does not dereference it
-  // in the constructor or destructor.
-  explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
-  virtual ~MatchResultListener() = 0;  // Makes this class abstract.
-
-  // Streams x to the underlying ostream; does nothing if the ostream
-  // is NULL.
-  template <typename T>
-  MatchResultListener& operator<<(const T& x) {
-    if (stream_ != NULL)
-      *stream_ << x;
-    return *this;
-  }
-
-  // Returns the underlying ostream.
-  ::std::ostream* stream() { return stream_; }
-
-  // Returns true iff the listener is interested in an explanation of
-  // the match result.  A matcher's MatchAndExplain() method can use
-  // this information to avoid generating the explanation when no one
-  // intends to hear it.
-  bool IsInterested() const { return stream_ != NULL; }
-
- private:
-  ::std::ostream* const stream_;
-
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener);
-};
-
-inline MatchResultListener::~MatchResultListener() {
-}
-
-// An instance of a subclass of this knows how to describe itself as a
-// matcher.
-class MatcherDescriberInterface {
- public:
-  virtual ~MatcherDescriberInterface() {}
-
-  // Describes this matcher to an ostream.  The function should print
-  // a verb phrase that describes the property a value matching this
-  // matcher should have.  The subject of the verb phrase is the value
-  // being matched.  For example, the DescribeTo() method of the Gt(7)
-  // matcher prints "is greater than 7".
-  virtual void DescribeTo(::std::ostream* os) const = 0;
-
-  // Describes the negation of this matcher to an ostream.  For
-  // example, if the description of this matcher is "is greater than
-  // 7", the negated description could be "is not greater than 7".
-  // You are not required to override this when implementing
-  // MatcherInterface, but it is highly advised so that your matcher
-  // can produce good error messages.
-  virtual void DescribeNegationTo(::std::ostream* os) const {
-    *os << "not (";
-    DescribeTo(os);
-    *os << ")";
-  }
-};
-
-// The implementation of a matcher.
-template <typename T>
-class MatcherInterface : public MatcherDescriberInterface {
- public:
-  // Returns true iff the matcher matches x; also explains the match
-  // result to 'listener' if necessary (see the next paragraph), in
-  // the form of a non-restrictive relative clause ("which ...",
-  // "whose ...", etc) that describes x.  For example, the
-  // MatchAndExplain() method of the Pointee(...) matcher should
-  // generate an explanation like "which points to ...".
-  //
-  // Implementations of MatchAndExplain() should add an explanation of
-  // the match result *if and only if* they can provide additional
-  // information that's not already present (or not obvious) in the
-  // print-out of x and the matcher's description.  Whether the match
-  // succeeds is not a factor in deciding whether an explanation is
-  // needed, as sometimes the caller needs to print a failure message
-  // when the match succeeds (e.g. when the matcher is used inside
-  // Not()).
-  //
-  // For example, a "has at least 10 elements" matcher should explain
-  // what the actual element count is, regardless of the match result,
-  // as it is useful information to the reader; on the other hand, an
-  // "is empty" matcher probably only needs to explain what the actual
-  // size is when the match fails, as it's redundant to say that the
-  // size is 0 when the value is already known to be empty.
-  //
-  // You should override this method when defining a new matcher.
-  //
-  // It's the responsibility of the caller (Google Mock) to guarantee
-  // that 'listener' is not NULL.  This helps to simplify a matcher's
-  // implementation when it doesn't care about the performance, as it
-  // can talk to 'listener' without checking its validity first.
-  // However, in order to implement dummy listeners efficiently,
-  // listener->stream() may be NULL.
-  virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;
-
-  // Inherits these methods from MatcherDescriberInterface:
-  //   virtual void DescribeTo(::std::ostream* os) const = 0;
-  //   virtual void DescribeNegationTo(::std::ostream* os) const;
-};
-
-// A match result listener that stores the explanation in a string.
-class StringMatchResultListener : public MatchResultListener {
- public:
-  StringMatchResultListener() : MatchResultListener(&ss_) {}
-
-  // Returns the explanation accumulated so far.
-  internal::string str() const { return ss_.str(); }
-
-  // Clears the explanation accumulated so far.
-  void Clear() { ss_.str(""); }
-
- private:
-  ::std::stringstream ss_;
-
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(StringMatchResultListener);
-};
-
-namespace internal {
-
-struct AnyEq {
-  template <typename A, typename B>
-  bool operator()(const A& a, const B& b) const { return a == b; }
-};
-struct AnyNe {
-  template <typename A, typename B>
-  bool operator()(const A& a, const B& b) const { return a != b; }
-};
-struct AnyLt {
-  template <typename A, typename B>
-  bool operator()(const A& a, const B& b) const { return a < b; }
-};
-struct AnyGt {
-  template <typename A, typename B>
-  bool operator()(const A& a, const B& b) const { return a > b; }
-};
-struct AnyLe {
-  template <typename A, typename B>
-  bool operator()(const A& a, const B& b) const { return a <= b; }
-};
-struct AnyGe {
-  template <typename A, typename B>
-  bool operator()(const A& a, const B& b) const { return a >= b; }
-};
-
-// A match result listener that ignores the explanation.
-class DummyMatchResultListener : public MatchResultListener {
- public:
-  DummyMatchResultListener() : MatchResultListener(NULL) {}
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener);
-};
-
-// A match result listener that forwards the explanation to a given
-// ostream.  The difference between this and MatchResultListener is
-// that the former is concrete.
-class StreamMatchResultListener : public MatchResultListener {
- public:
-  explicit StreamMatchResultListener(::std::ostream* os)
-      : MatchResultListener(os) {}
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener);
-};
-
-// An internal class for implementing Matcher<T>, which will derive
-// from it.  We put functionalities common to all Matcher<T>
-// specializations here to avoid code duplication.
-template <typename T>
-class MatcherBase {
- public:
-  // Returns true iff the matcher matches x; also explains the match
-  // result to 'listener'.
-  bool MatchAndExplain(T x, MatchResultListener* listener) const {
-    return impl_->MatchAndExplain(x, listener);
-  }
-
-  // Returns true iff this matcher matches x.
-  bool Matches(T x) const {
-    DummyMatchResultListener dummy;
-    return MatchAndExplain(x, &dummy);
-  }
-
-  // Describes this matcher to an ostream.
-  void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
-
-  // Describes the negation of this matcher to an ostream.
-  void DescribeNegationTo(::std::ostream* os) const {
-    impl_->DescribeNegationTo(os);
-  }
-
-  // Explains why x matches, or doesn't match, the matcher.
-  void ExplainMatchResultTo(T x, ::std::ostream* os) const {
-    StreamMatchResultListener listener(os);
-    MatchAndExplain(x, &listener);
-  }
-
-  // Returns the describer for this matcher object; retains ownership
-  // of the describer, which is only guaranteed to be alive when
-  // this matcher object is alive.
-  const MatcherDescriberInterface* GetDescriber() const {
-    return impl_.get();
-  }
-
- protected:
-  MatcherBase() {}
-
-  // Constructs a matcher from its implementation.
-  explicit MatcherBase(const MatcherInterface<T>* impl)
-      : impl_(impl) {}
-
-  virtual ~MatcherBase() {}
-
- private:
-  // shared_ptr (util/gtl/shared_ptr.h) and linked_ptr have similar
-  // interfaces.  The former dynamically allocates a chunk of memory
-  // to hold the reference count, while the latter tracks all
-  // references using a circular linked list without allocating
-  // memory.  It has been observed that linked_ptr performs better in
-  // typical scenarios.  However, shared_ptr can out-perform
-  // linked_ptr when there are many more uses of the copy constructor
-  // than the default constructor.
-  //
-  // If performance becomes a problem, we should see if using
-  // shared_ptr helps.
-  ::testing::internal::linked_ptr<const MatcherInterface<T> > impl_;
-};
-
-}  // namespace internal
-
-// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)
-// object that can check whether a value of type T matches.  The
-// implementation of Matcher<T> is just a linked_ptr to const
-// MatcherInterface<T>, so copying is fairly cheap.  Don't inherit
-// from Matcher!
-template <typename T>
-class Matcher : public internal::MatcherBase<T> {
- public:
-  // Constructs a null matcher.  Needed for storing Matcher objects in STL
-  // containers.  A default-constructed matcher is not yet initialized.  You
-  // cannot use it until a valid value has been assigned to it.
-  explicit Matcher() {}  // NOLINT
-
-  // Constructs a matcher from its implementation.
-  explicit Matcher(const MatcherInterface<T>* impl)
-      : internal::MatcherBase<T>(impl) {}
-
-  // Implicit constructor here allows people to write
-  // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
-  Matcher(T value);  // NOLINT
-};
-
-// The following two specializations allow the user to write str
-// instead of Eq(str) and "foo" instead of Eq("foo") when a string
-// matcher is expected.
-template <>
-class GTEST_API_ Matcher<const internal::string&>
-    : public internal::MatcherBase<const internal::string&> {
- public:
-  Matcher() {}
-
-  explicit Matcher(const MatcherInterface<const internal::string&>* impl)
-      : internal::MatcherBase<const internal::string&>(impl) {}
-
-  // Allows the user to write str instead of Eq(str) sometimes, where
-  // str is a string object.
-  Matcher(const internal::string& s);  // NOLINT
-
-  // Allows the user to write "foo" instead of Eq("foo") sometimes.
-  Matcher(const char* s);  // NOLINT
-};
-
-template <>
-class GTEST_API_ Matcher<internal::string>
-    : public internal::MatcherBase<internal::string> {
- public:
-  Matcher() {}
-
-  explicit Matcher(const MatcherInterface<internal::string>* impl)
-      : internal::MatcherBase<internal::string>(impl) {}
-
-  // Allows the user to write str instead of Eq(str) sometimes, where
-  // str is a string object.
-  Matcher(const internal::string& s);  // NOLINT
-
-  // Allows the user to write "foo" instead of Eq("foo") sometimes.
-  Matcher(const char* s);  // NOLINT
-};
-
-#if GTEST_HAS_STRING_PIECE_
-// The following two specializations allow the user to write str
-// instead of Eq(str) and "foo" instead of Eq("foo") when a StringPiece
-// matcher is expected.
-template <>
-class GTEST_API_ Matcher<const StringPiece&>
-    : public internal::MatcherBase<const StringPiece&> {
- public:
-  Matcher() {}
-
-  explicit Matcher(const MatcherInterface<const StringPiece&>* impl)
-      : internal::MatcherBase<const StringPiece&>(impl) {}
-
-  // Allows the user to write str instead of Eq(str) sometimes, where
-  // str is a string object.
-  Matcher(const internal::string& s);  // NOLINT
-
-  // Allows the user to write "foo" instead of Eq("foo") sometimes.
-  Matcher(const char* s);  // NOLINT
-
-  // Allows the user to pass StringPieces directly.
-  Matcher(StringPiece s);  // NOLINT
-};
-
-template <>
-class GTEST_API_ Matcher<StringPiece>
-    : public internal::MatcherBase<StringPiece> {
- public:
-  Matcher() {}
-
-  explicit Matcher(const MatcherInterface<StringPiece>* impl)
-      : internal::MatcherBase<StringPiece>(impl) {}
-
-  // Allows the user to write str instead of Eq(str) sometimes, where
-  // str is a string object.
-  Matcher(const internal::string& s);  // NOLINT
-
-  // Allows the user to write "foo" instead of Eq("foo") sometimes.
-  Matcher(const char* s);  // NOLINT
-
-  // Allows the user to pass StringPieces directly.
-  Matcher(StringPiece s);  // NOLINT
-};
-#endif  // GTEST_HAS_STRING_PIECE_
-
-// The PolymorphicMatcher class template makes it easy to implement a
-// polymorphic matcher (i.e. a matcher that can match values of more
-// than one type, e.g. Eq(n) and NotNull()).
-//
-// To define a polymorphic matcher, a user should provide an Impl
-// class that has a DescribeTo() method and a DescribeNegationTo()
-// method, and define a member function (or member function template)
-//
-//   bool MatchAndExplain(const Value& value,
-//                        MatchResultListener* listener) const;
-//
-// See the definition of NotNull() for a complete example.
-template <class Impl>
-class PolymorphicMatcher {
- public:
-  explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
-
-  // Returns a mutable reference to the underlying matcher
-  // implementation object.
-  Impl& mutable_impl() { return impl_; }
-
-  // Returns an immutable reference to the underlying matcher
-  // implementation object.
-  const Impl& impl() const { return impl_; }
-
-  template <typename T>
-  operator Matcher<T>() const {
-    return Matcher<T>(new MonomorphicImpl<T>(impl_));
-  }
-
- private:
-  template <typename T>
-  class MonomorphicImpl : public MatcherInterface<T> {
-   public:
-    explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
-
-    virtual void DescribeTo(::std::ostream* os) const {
-      impl_.DescribeTo(os);
-    }
-
-    virtual void DescribeNegationTo(::std::ostream* os) const {
-      impl_.DescribeNegationTo(os);
-    }
-
-    virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
-      return impl_.MatchAndExplain(x, listener);
-    }
-
-   private:
-    const Impl impl_;
-
-    GTEST_DISALLOW_ASSIGN_(MonomorphicImpl);
-  };
-
-  Impl impl_;
-
-  GTEST_DISALLOW_ASSIGN_(PolymorphicMatcher);
-};
-
-// Creates a matcher from its implementation.  This is easier to use
-// than the Matcher<T> constructor as it doesn't require you to
-// explicitly write the template argument, e.g.
-//
-//   MakeMatcher(foo);
-// vs
-//   Matcher<const string&>(foo);
-template <typename T>
-inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
-  return Matcher<T>(impl);
-}
-
-// Creates a polymorphic matcher from its implementation.  This is
-// easier to use than the PolymorphicMatcher<Impl> constructor as it
-// doesn't require you to explicitly write the template argument, e.g.
-//
-//   MakePolymorphicMatcher(foo);
-// vs
-//   PolymorphicMatcher<TypeOfFoo>(foo);
-template <class Impl>
-inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
-  return PolymorphicMatcher<Impl>(impl);
-}
-
-// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
-// and MUST NOT BE USED IN USER CODE!!!
-namespace internal {
-
-// The MatcherCastImpl class template is a helper for implementing
-// MatcherCast().  We need this helper in order to partially
-// specialize the implementation of MatcherCast() (C++ allows
-// class/struct templates to be partially specialized, but not
-// function templates.).
-
-// This general version is used when MatcherCast()'s argument is a
-// polymorphic matcher (i.e. something that can be converted to a
-// Matcher but is not one yet; for example, Eq(value)) or a value (for
-// example, "hello").
-template <typename T, typename M>
-class MatcherCastImpl {
- public:
-  static Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
-    // M can be a polymorhic matcher, in which case we want to use
-    // its conversion operator to create Matcher<T>.  Or it can be a value
-    // that should be passed to the Matcher<T>'s constructor.
-    //
-    // We can't call Matcher<T>(polymorphic_matcher_or_value) when M is a
-    // polymorphic matcher because it'll be ambiguous if T has an implicit
-    // constructor from M (this usually happens when T has an implicit
-    // constructor from any type).
-    //
-    // It won't work to unconditionally implict_cast
-    // polymorphic_matcher_or_value to Matcher<T> because it won't trigger
-    // a user-defined conversion from M to T if one exists (assuming M is
-    // a value).
-    return CastImpl(
-        polymorphic_matcher_or_value,
-        BooleanConstant<
-            internal::ImplicitlyConvertible<M, Matcher<T> >::value>());
-  }
-
- private:
-  static Matcher<T> CastImpl(const M& value, BooleanConstant<false>) {
-    // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
-    // matcher.  It must be a value then.  Use direct initialization to create
-    // a matcher.
-    return Matcher<T>(ImplicitCast_<T>(value));
-  }
-
-  static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value,
-                             BooleanConstant<true>) {
-    // M is implicitly convertible to Matcher<T>, which means that either
-    // M is a polymorhpic matcher or Matcher<T> has an implicit constructor
-    // from M.  In both cases using the implicit conversion will produce a
-    // matcher.
-    //
-    // Even if T has an implicit constructor from M, it won't be called because
-    // creating Matcher<T> would require a chain of two user-defined conversions
-    // (first to create T from M and then to create Matcher<T> from T).
-    return polymorphic_matcher_or_value;
-  }
-};
-
-// This more specialized version is used when MatcherCast()'s argument
-// is already a Matcher.  This only compiles when type T can be
-// statically converted to type U.
-template <typename T, typename U>
-class MatcherCastImpl<T, Matcher<U> > {
- public:
-  static Matcher<T> Cast(const Matcher<U>& source_matcher) {
-    return Matcher<T>(new Impl(source_matcher));
-  }
-
- private:
-  class Impl : public MatcherInterface<T> {
-   public:
-    explicit Impl(const Matcher<U>& source_matcher)
-        : source_matcher_(source_matcher) {}
-
-    // We delegate the matching logic to the source matcher.
-    virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
-      return source_matcher_.MatchAndExplain(static_cast<U>(x), listener);
-    }
-
-    virtual void DescribeTo(::std::ostream* os) const {
-      source_matcher_.DescribeTo(os);
-    }
-
-    virtual void DescribeNegationTo(::std::ostream* os) const {
-      source_matcher_.DescribeNegationTo(os);
-    }
-
-   private:
-    const Matcher<U> source_matcher_;
-
-    GTEST_DISALLOW_ASSIGN_(Impl);
-  };
-};
-
-// This even more specialized version is used for efficiently casting
-// a matcher to its own type.
-template <typename T>
-class MatcherCastImpl<T, Matcher<T> > {
- public:
-  static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }
-};
-
-}  // namespace internal
-
-// In order to be safe and clear, casting between different matcher
-// types is done explicitly via MatcherCast<T>(m), which takes a
-// matcher m and returns a Matcher<T>.  It compiles only when T can be
-// statically converted to the argument type of m.
-template <typename T, typename M>
-inline Matcher<T> MatcherCast(const M& matcher) {
-  return internal::MatcherCastImpl<T, M>::Cast(matcher);
-}
-
-// Implements SafeMatcherCast().
-//
-// We use an intermediate class to do the actual safe casting as Nokia's
-// Symbian compiler cannot decide between
-// template <T, M> ... (M) and
-// template <T, U> ... (const Matcher<U>&)
-// for function templates but can for member function templates.
-template <typename T>
-class SafeMatcherCastImpl {
- public:
-  // This overload handles polymorphic matchers and values only since
-  // monomorphic matchers are handled by the next one.
-  template <typename M>
-  static inline Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
-    return internal::MatcherCastImpl<T, M>::Cast(polymorphic_matcher_or_value);
-  }
-
-  // This overload handles monomorphic matchers.
-  //
-  // In general, if type T can be implicitly converted to type U, we can
-  // safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is
-  // contravariant): just keep a copy of the original Matcher<U>, convert the
-  // argument from type T to U, and then pass it to the underlying Matcher<U>.
-  // The only exception is when U is a reference and T is not, as the
-  // underlying Matcher<U> may be interested in the argument's address, which
-  // is not preserved in the conversion from T to U.
-  template <typename U>
-  static inline Matcher<T> Cast(const Matcher<U>& matcher) {
-    // Enforce that T can be implicitly converted to U.
-    GTEST_COMPILE_ASSERT_((internal::ImplicitlyConvertible<T, U>::value),
-                          T_must_be_implicitly_convertible_to_U);
-    // Enforce that we are not converting a non-reference type T to a reference
-    // type U.
-    GTEST_COMPILE_ASSERT_(
-        internal::is_reference<T>::value || !internal::is_reference<U>::value,
-        cannot_convert_non_referentce_arg_to_reference);
-    // In case both T and U are arithmetic types, enforce that the
-    // conversion is not lossy.
-    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT;
-    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU;
-    const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther;
-    const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther;
-    GTEST_COMPILE_ASSERT_(
-        kTIsOther || kUIsOther ||
-        (internal::LosslessArithmeticConvertible<RawT, RawU>::value),
-        conversion_of_arithmetic_types_must_be_lossless);
-    return MatcherCast<T>(matcher);
-  }
-};
-
-template <typename T, typename M>
-inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher) {
-  return SafeMatcherCastImpl<T>::Cast(polymorphic_matcher);
-}
-
-// A<T>() returns a matcher that matches any value of type T.
-template <typename T>
-Matcher<T> A();
-
-// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
-// and MUST NOT BE USED IN USER CODE!!!
-namespace internal {
-
-// If the explanation is not empty, prints it to the ostream.
-inline void PrintIfNotEmpty(const internal::string& explanation,
-                            ::std::ostream* os) {
-  if (explanation != "" && os != NULL) {
-    *os << ", " << explanation;
-  }
-}
-
-// Returns true if the given type name is easy to read by a human.
-// This is used to decide whether printing the type of a value might
-// be helpful.
-inline bool IsReadableTypeName(const string& type_name) {
-  // We consider a type name readable if it's short or doesn't contain
-  // a template or function type.
-  return (type_name.length() <= 20 ||
-          type_name.find_first_of("<(") == string::npos);
-}
-
-// Matches the value against the given matcher, prints the value and explains
-// the match result to the listener. Returns the match result.
-// 'listener' must not be NULL.
-// Value cannot be passed by const reference, because some matchers take a
-// non-const argument.
-template <typename Value, typename T>
-bool MatchPrintAndExplain(Value& value, const Matcher<T>& matcher,
-                          MatchResultListener* listener) {
-  if (!listener->IsInterested()) {
-    // If the listener is not interested, we do not need to construct the
-    // inner explanation.
-    return matcher.Matches(value);
-  }
-
-  StringMatchResultListener inner_listener;
-  const bool match = matcher.MatchAndExplain(value, &inner_listener);
-
-  UniversalPrint(value, listener->stream());
-#if GTEST_HAS_RTTI
-  const string& type_name = GetTypeName<Value>();
-  if (IsReadableTypeName(type_name))
-    *listener->stream() << " (of type " << type_name << ")";
-#endif
-  PrintIfNotEmpty(inner_listener.str(), listener->stream());
-
-  return match;
-}
-
-// An internal helper class for doing compile-time loop on a tuple's
-// fields.
-template <size_t N>
-class TuplePrefix {
- public:
-  // TuplePrefix<N>::Matches(matcher_tuple, value_tuple) returns true
-  // iff the first N fields of matcher_tuple matches the first N
-  // fields of value_tuple, respectively.
-  template <typename MatcherTuple, typename ValueTuple>
-  static bool Matches(const MatcherTuple& matcher_tuple,
-                      const ValueTuple& value_tuple) {
-    return TuplePrefix<N - 1>::Matches(matcher_tuple, value_tuple)
-        && get<N - 1>(matcher_tuple).Matches(get<N - 1>(value_tuple));
-  }
-
-  // TuplePrefix<N>::ExplainMatchFailuresTo(matchers, values, os)
-  // describes failures in matching the first N fields of matchers
-  // against the first N fields of values.  If there is no failure,
-  // nothing will be streamed to os.
-  template <typename MatcherTuple, typename ValueTuple>
-  static void ExplainMatchFailuresTo(const MatcherTuple& matchers,
-                                     const ValueTuple& values,
-                                     ::std::ostream* os) {
-    // First, describes failures in the first N - 1 fields.
-    TuplePrefix<N - 1>::ExplainMatchFailuresTo(matchers, values, os);
-
-    // Then describes the failure (if any) in the (N - 1)-th (0-based)
-    // field.
-    typename tuple_element<N - 1, MatcherTuple>::type matcher =
-        get<N - 1>(matchers);
-    typedef typename tuple_element<N - 1, ValueTuple>::type Value;
-    Value value = get<N - 1>(values);
-    StringMatchResultListener listener;
-    if (!matcher.MatchAndExplain(value, &listener)) {
-      // TODO(wan): include in the message the name of the parameter
-      // as used in MOCK_METHOD*() when possible.
-      *os << "  Expected arg #" << N - 1 << ": ";
-      get<N - 1>(matchers).DescribeTo(os);
-      *os << "\n           Actual: ";
-      // We remove the reference in type Value to prevent the
-      // universal printer from printing the address of value, which
-      // isn't interesting to the user most of the time.  The
-      // matcher's MatchAndExplain() method handles the case when
-      // the address is interesting.
-      internal::UniversalPrint(value, os);
-      PrintIfNotEmpty(listener.str(), os);
-      *os << "\n";
-    }
-  }
-};
-
-// The base case.
-template <>
-class TuplePrefix<0> {
- public:
-  template <typename MatcherTuple, typename ValueTuple>
-  static bool Matches(const MatcherTuple& /* matcher_tuple */,
-                      const ValueTuple& /* value_tuple */) {
-    return true;
-  }
-
-  template <typename MatcherTuple, typename ValueTuple>
-  static void ExplainMatchFailuresTo(const MatcherTuple& /* matchers */,
-                                     const ValueTuple& /* values */,
-                                     ::std::ostream* /* os */) {}
-};
-
-// TupleMatches(matcher_tuple, value_tuple) returns true iff all
-// matchers in matcher_tuple match the corresponding fields in
-// value_tuple.  It is a compiler error if matcher_tuple and
-// value_tuple have different number of fields or incompatible field
-// types.
-template <typename MatcherTuple, typename ValueTuple>
-bool TupleMatches(const MatcherTuple& matcher_tuple,
-                  const ValueTuple& value_tuple) {
-  // Makes sure that matcher_tuple and value_tuple have the same
-  // number of fields.
-  GTEST_COMPILE_ASSERT_(tuple_size<MatcherTuple>::value ==
-                        tuple_size<ValueTuple>::value,
-                        matcher_and_value_have_different_numbers_of_fields);
-  return TuplePrefix<tuple_size<ValueTuple>::value>::
-      Matches(matcher_tuple, value_tuple);
-}
-
-// Describes failures in matching matchers against values.  If there
-// is no failure, nothing will be streamed to os.
-template <typename MatcherTuple, typename ValueTuple>
-void ExplainMatchFailureTupleTo(const MatcherTuple& matchers,
-                                const ValueTuple& values,
-                                ::std::ostream* os) {
-  TuplePrefix<tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo(
-      matchers, values, os);
-}
-
-// TransformTupleValues and its helper.
-//
-// TransformTupleValuesHelper hides the internal machinery that
-// TransformTupleValues uses to implement a tuple traversal.
-template <typename Tuple, typename Func, typename OutIter>
-class TransformTupleValuesHelper {
- private:
-  typedef ::testing::tuple_size<Tuple> TupleSize;
-
- public:
-  // For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'.
-  // Returns the final value of 'out' in case the caller needs it.
-  static OutIter Run(Func f, const Tuple& t, OutIter out) {
-    return IterateOverTuple<Tuple, TupleSize::value>()(f, t, out);
-  }
-
- private:
-  template <typename Tup, size_t kRemainingSize>
-  struct IterateOverTuple {
-    OutIter operator() (Func f, const Tup& t, OutIter out) const {
-      *out++ = f(::testing::get<TupleSize::value - kRemainingSize>(t));
-      return IterateOverTuple<Tup, kRemainingSize - 1>()(f, t, out);
-    }
-  };
-  template <typename Tup>
-  struct IterateOverTuple<Tup, 0> {
-    OutIter operator() (Func /* f */, const Tup& /* t */, OutIter out) const {
-      return out;
-    }
-  };
-};
-
-// Successively invokes 'f(element)' on each element of the tuple 't',
-// appending each result to the 'out' iterator. Returns the final value
-// of 'out'.
-template <typename Tuple, typename Func, typename OutIter>
-OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) {
-  return TransformTupleValuesHelper<Tuple, Func, OutIter>::Run(f, t, out);
-}
-
-// Implements A<T>().
-template <typename T>
-class AnyMatcherImpl : public MatcherInterface<T> {
- public:
-  virtual bool MatchAndExplain(
-      T /* x */, MatchResultListener* /* listener */) const { return true; }
-  virtual void DescribeTo(::std::ostream* os) const { *os << "is anything"; }
-  virtual void DescribeNegationTo(::std::ostream* os) const {
-    // This is mostly for completeness' safe, as it's not very useful
-    // to write Not(A<bool>()).  However we cannot completely rule out
-    // such a possibility, and it doesn't hurt to be prepared.
-    *os << "never matches";
-  }
-};
-
-// Implements _, a matcher that matches any value of any
-// type.  This is a polymorphic matcher, so we need a template type
-// conversion operator to make it appearing as a Matcher<T> for any
-// type T.
-class AnythingMatcher {
- public:
-  template <typename T>
-  operator Matcher<T>() const { return A<T>(); }
-};
-
-// Implements a matcher that compares a given value with a
-// pre-supplied value using one of the ==, <=, <, etc, operators.  The
-// two values being compared don't have to have the same type.
-//
-// The matcher defined here is polymorphic (for example, Eq(5) can be
-// used to match an int, a short, a double, etc).  Therefore we use
-// a template type conversion operator in the implementation.
-//
-// The following template definition assumes that the Rhs parameter is
-// a "bare" type (i.e. neither 'const T' nor 'T&').
-template <typename D, typename Rhs, typename Op>
-class ComparisonBase {
- public:
-  explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
-  template <typename Lhs>
-  operator Matcher<Lhs>() const {
-    return MakeMatcher(new Impl<Lhs>(rhs_));
-  }
-
- private:
-  template <typename Lhs>
-  class Impl : public MatcherInterface<Lhs> {
-   public:
-    explicit Impl(const Rhs& rhs) : rhs_(rhs) {}
-    virtual bool MatchAndExplain(
-        Lhs lhs, MatchResultListener* /* listener */) const {
-      return Op()(lhs, rhs_);
-    }
-    virtual void DescribeTo(::std::ostream* os) const {
-      *os << D::Desc() << " ";
-      UniversalPrint(rhs_, os);
-    }
-    virtual void DescribeNegationTo(::std::ostream* os) const {
-      *os << D::NegatedDesc() <<  " ";
-      UniversalPrint(rhs_, os);
-    }
-   private:
-    Rhs rhs_;
-    GTEST_DISALLOW_ASSIGN_(Impl);
-  };
-  Rhs rhs_;
-  GTEST_DISALLOW_ASSIGN_(ComparisonBase);
-};
-
-template <typename Rhs>
-class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
- public:
-  explicit EqMatcher(const Rhs& rhs)
-      : ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { }
-  static const char* Desc() { return "is equal to"; }
-  static const char* NegatedDesc() { return "isn't equal to"; }
-};
-template <typename Rhs>
-class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
- public:
-  explicit NeMatcher(const Rhs& rhs)
-      : ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { }
-  static const char* Desc() { return "isn't equal to"; }
-  static const char* NegatedDesc() { return "is equal to"; }
-};
-template <typename Rhs>
-class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
- public:
-  explicit LtMatcher(const Rhs& rhs)
-      : ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { }
-  static const char* Desc() { return "is <"; }
-  static const char* NegatedDesc() { return "isn't <"; }
-};
-template <typename Rhs>
-class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
- public:
-  explicit GtMatcher(const Rhs& rhs)
-      : ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { }
-  static const char* Desc() { return "is >"; }
-  static const char* NegatedDesc() { return "isn't >"; }
-};
-template <typename Rhs>
-class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
- public:
-  explicit LeMatcher(const Rhs& rhs)
-      : ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { }
-  static const char* Desc() { return "is <="; }
-  static const char* NegatedDesc() { return "isn't <="; }
-};
-template <typename Rhs>
-class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
- public:
-  explicit GeMatcher(const Rhs& rhs)
-      : ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { }
-  static const char* Desc() { return "is >="; }
-  static const char* NegatedDesc() { return "isn't >="; }
-};
-
-// Implements the polymorphic IsNull() matcher, which matches any raw or smart
-// pointer that is NULL.
-class IsNullMatcher {
- public:
-  template <typename Pointer>
-  bool MatchAndExplain(const Pointer& p,
-                       MatchResultListener* /* listener */) const {
-#if GTEST_LANG_CXX11
-    return p == nullptr;
-#else  // GTEST_LANG_CXX11
-    return GetRawPointer(p) == NULL;
-#endif  // GTEST_LANG_CXX11
-  }
-
-  void DescribeTo(::std::ostream* os) const { *os << "is NULL"; }
-  void DescribeNegationTo(::std::ostream* os) const {
-    *os << "isn't NULL";
-  }
-};
-
-// Implements the polymorphic NotNull() matcher, which matches any raw or smart
-// pointer that is not NULL.
-class NotNullMatcher {
- public:
-  template <typename Pointer>
-  bool MatchAndExplain(const Pointer& p,
-                       MatchResultListener* /* listener */) const {
-#if GTEST_LANG_CXX11
-    return p != nullptr;
-#else  // GTEST_LANG_CXX11
-    return GetRawPointer(p) != NULL;
-#endif  // GTEST_LANG_CXX11
-  }
-
-  void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; }
-  void DescribeNegationTo(::std::ostream* os) const {
-    *os << "is NULL";
-  }
-};
-
-// Ref(variable) matches any argument that is a reference to
-// 'variable'.  This matcher is polymorphic as it can match any
-// super type of the type of 'variable'.
-//
-// The RefMatcher template class implements Ref(variable).  It can
-// only be instantiated with a reference type.  This prevents a user
-// from mistakenly using Ref(x) to match a non-reference function
-// argument.  For example, the following will righteously cause a
-// compiler error:
-//
-//   int n;
-//   Matcher<int> m1 = Ref(n);   // This won't compile.
-//   Matcher<int&> m2 = Ref(n);  // This will compile.
-template <typename T>
-class RefMatcher;
-
-template <typename T>
-class RefMatcher<T&> {
-  // Google Mock is a generic framework and thus needs to support
-  // mocking any function types, including those that take non-const
-  // reference arguments.  Therefore the template parameter T (and
-  // Super below) can be instantiated to either a const type or a
-  // non-const type.
- public:
-  // RefMatcher() takes a T& instead of const T&, as we want the
-  // compiler to catch using Ref(const_value) as a matcher for a
-  // non-const reference.
-  explicit RefMatcher(T& x) : object_(x) {}  // NOLINT
-
-  template <typename Super>
-  operator Matcher<Super&>() const {
-    // By passing object_ (type T&) to Impl(), which expects a Super&,
-    // we make sure that Super is a super type of T.  In particular,
-    // this catches using Ref(const_value) as a matcher for a
-    // non-const reference, as you cannot implicitly convert a const
-    // reference to a non-const reference.
-    return MakeMatcher(new Impl<Super>(object_));
-  }
-
- private:
-  template <typename Super>
-  class Impl : public MatcherInterface<Super&> {
-   public:
-    explicit Impl(Super& x) : object_(x) {}  // NOLINT
-
-    // MatchAndExplain() takes a Super& (as opposed to const Super&)
-    // in order to match the interface MatcherInterface<Super&>.
-    virtual bool MatchAndExplain(
-        Super& x, MatchResultListener* listener) const {
-      *listener << "which is located @" << static_cast<const void*>(&x);
-      return &x == &object_;
-    }
-
-    virtual void DescribeTo(::std::ostream* os) const {
-      *os << "references the variable ";
-      UniversalPrinter<Super&>::Print(object_, os);
-    }
-
-    virtual void DescribeNegationTo(::std::ostream* os) const {
-      *os << "does not reference the variable ";
-      UniversalPrinter<Super&>::Print(object_, os);
-    }
-
-   private:
-    const Super& object_;
-
-    GTEST_DISALLOW_ASSIGN_(Impl);
-  };
-
-  T& object_;
-
-  GTEST_DISALLOW_ASSIGN_(RefMatcher);
-};
-
-// Polymorphic helper functions for narrow and wide string matchers.
-inline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) {
-  return String::CaseInsensitiveCStringEquals(lhs, rhs);
-}
-
-inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs,
-                                         const wchar_t* rhs) {
-  return String::CaseInsensitiveWideCStringEquals(lhs, rhs);
-}
-
-// String comparison for narrow or wide strings that can have embedded NUL
-// characters.
-template <typename StringType>
-bool CaseInsensitiveStringEquals(const StringType& s1,
-                                 const StringType& s2) {
-  // Are the heads equal?
-  if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) {
-    return false;
-  }
-
-  // Skip the equal heads.
-  const typename StringType::value_type nul = 0;
-  const size_t i1 = s1.find(nul), i2 = s2.find(nul);
-
-  // Are we at the end of either s1 or s2?
-  if (i1 == StringType::npos || i2 == StringType::npos) {
-    return i1 == i2;
-  }
-
-  // Are the tails equal?
-  return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1));
-}
-
-// String matchers.
-
-// Implements equality-based string matchers like StrEq, StrCaseNe, and etc.
-template <typename StringType>
-class StrEqualityMatcher {
- public:
-  StrEqualityMatcher(const StringType& str, bool expect_eq,
-                     bool case_sensitive)
-      : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {}
-
-  // Accepts pointer types, particularly:
-  //   const char*
-  //   char*
-  //   const wchar_t*
-  //   wchar_t*
-  template <typename CharType>
-  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
-    if (s == NULL) {
-      return !expect_eq_;
-    }
-    return MatchAndExplain(StringType(s), listener);
-  }
-
-  // Matches anything that can convert to StringType.
-  //
-  // This is a template, not just a plain function with const StringType&,
-  // because StringPiece has some interfering non-explicit constructors.
-  template <typename MatcheeStringType>
-  bool MatchAndExplain(const MatcheeStringType& s,
-                       MatchResultListener* /* listener */) const {
-    const StringType& s2(s);
-    const bool eq = case_sensitive_ ? s2 == string_ :
-        CaseInsensitiveStringEquals(s2, string_);
-    return expect_eq_ == eq;
-  }
-
-  void DescribeTo(::std::ostream* os) const {
-    DescribeToHelper(expect_eq_, os);
-  }
-
-  void DescribeNegationTo(::std::ostream* os) const {
-    DescribeToHelper(!expect_eq_, os);
-  }
-
- private:
-  void DescribeToHelper(bool expect_eq, ::std::ostream* os) const {
-    *os << (expect_eq ? "is " : "isn't ");
-    *os << "equal to ";
-    if (!case_sensitive_) {
-      *os << "(ignoring case) ";
-    }
-    UniversalPrint(string_, os);
-  }
-
-  const StringType string_;
-  const bool expect_eq_;
-  const bool case_sensitive_;
-
-  GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher);
-};
-
-// Implements the polymorphic HasSubstr(substring) matcher, which
-// can be used as a Matcher<T> as long as T can be converted to a
-// string.
-template <typename StringType>
-class HasSubstrMatcher {
- public:
-  explicit HasSubstrMatcher(const StringType& substring)
-      : substring_(substring) {}
-
-  // Accepts pointer types, particularly:
-  //   const char*
-  //   char*
-  //   const wchar_t*
-  //   wchar_t*
-  template <typename CharType>
-  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
-    return s != NULL && MatchAndExplain(StringType(s), listener);
-  }
-
-  // Matches anything that can convert to StringType.
-  //
-  // This is a template, not just a plain function with const StringType&,
-  // because StringPiece has some interfering non-explicit constructors.
-  template <typename MatcheeStringType>
-  bool MatchAndExplain(const MatcheeStringType& s,
-                       MatchResultListener* /* listener */) const {
-    const StringType& s2(s);
-    return s2.find(substring_) != StringType::npos;
-  }
-
-  // Describes what this matcher matches.
-  void DescribeTo(::std::ostream* os) const {
-    *os << "has substring ";
-    UniversalPrint(substring_, os);
-  }
-
-  void DescribeNegationTo(::std::ostream* os) const {
-    *os << "has no substring ";
-    UniversalPrint(substring_, os);
-  }
-
- private:
-  const StringType substring_;
-
-  GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher);
-};
-
-// Implements the polymorphic StartsWith(substring) matcher, which
-// can be used as a Matcher<T> as long as T can be converted to a
-// string.
-template <typename StringType>
-class StartsWithMatcher {
- public:
-  explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {
-  }
-
-  // Accepts pointer types, particularly:
-  //   const char*
-  //   char*
-  //   const wchar_t*
-  //   wchar_t*
-  template <typename CharType>
-  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
-    return s != NULL && MatchAndExplain(StringType(s), listener);
-  }
-
-  // Matches anything that can convert to StringType.
-  //
-  // This is a template, not just a plain function with const StringType&,
-  // because StringPiece has some interfering non-explicit constructors.
-  template <typename MatcheeStringType>
-  bool MatchAndExplain(const MatcheeStringType& s,
-                       MatchResultListener* /* listener */) const {
-    const StringType& s2(s);
-    return s2.length() >= prefix_.length() &&
-        s2.substr(0, prefix_.length()) == prefix_;
-  }
-
-  void DescribeTo(::std::ostream* os) const {
-    *os << "starts with ";
-    UniversalPrint(prefix_, os);
-  }
-
-  void DescribeNegationTo(::std::ostream* os) const {
-    *os << "doesn't start with ";
-    UniversalPrint(prefix_, os);
-  }
-
- private:
-  const StringType prefix_;
-
-  GTEST_DISALLOW_ASSIGN_(StartsWithMatcher);
-};
-
-// Implements the polymorphic EndsWith(substring) matcher, which
-// can be used as a Matcher<T> as long as T can be converted to a
-// string.
-template <typename StringType>
-class EndsWithMatcher {
- public:
-  explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {}
-
-  // Accepts pointer types, particularly:
-  //   const char*
-  //   char*
-  //   const wchar_t*
-  //   wchar_t*
-  template <typename CharType>
-  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
-    return s != NULL && MatchAndExplain(StringType(s), listener);
-  }
-
-  // Matches anything that can convert to StringType.
-  //
-  // This is a template, not just a plain function with const StringType&,
-  // because StringPiece has some interfering non-explicit constructors.
-  template <typename MatcheeStringType>
-  bool MatchAndExplain(const MatcheeStringType& s,
-                       MatchResultListener* /* listener */) const {
-    const StringType& s2(s);
-    return s2.length() >= suffix_.length() &&
-        s2.substr(s2.length() - suffix_.length()) == suffix_;
-  }
-
-  void DescribeTo(::std::ostream* os) const {
-    *os << "ends with ";
-    UniversalPrint(suffix_, os);
-  }
-
-  void DescribeNegationTo(::std::ostream* os) const {
-    *os << "doesn't end with ";
-    UniversalPrint(suffix_, os);
-  }
-
- private:
-  const StringType suffix_;
-
-  GTEST_DISALLOW_ASSIGN_(EndsWithMatcher);
-};
-
-// Implements polymorphic matchers MatchesRegex(regex) and
-// ContainsRegex(regex), which can be used as a Matcher<T> as long as
-// T can be converted to a string.
-class MatchesRegexMatcher {
- public:
-  MatchesRegexMatcher(const RE* regex, bool full_match)
-      : regex_(regex), full_match_(full_match) {}
-
-  // Accepts pointer types, particularly:
-  //   const char*
-  //   char*
-  //   const wchar_t*
-  //   wchar_t*
-  template <typename CharType>
-  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
-    return s != NULL && MatchAndExplain(internal::string(s), listener);
-  }
-
-  // Matches anything that can convert to internal::string.
-  //
-  // This is a template, not just a plain function with const internal::string&,
-  // because StringPiece has some interfering non-explicit constructors.
-  template <class MatcheeStringType>
-  bool MatchAndExplain(const MatcheeStringType& s,
-                       MatchResultListener* /* listener */) const {
-    const internal::string& s2(s);
-    return full_match_ ? RE::FullMatch(s2, *regex_) :
-        RE::PartialMatch(s2, *regex_);
-  }
-
-  void DescribeTo(::std::ostream* os) const {
-    *os << (full_match_ ? "matches" : "contains")
-        << " regular expression ";
-    UniversalPrinter<internal::string>::Print(regex_->pattern(), os);
-  }
-
-  void DescribeNegationTo(::std::ostream* os) const {
-    *os << "doesn't " << (full_match_ ? "match" : "contain")
-        << " regular expression ";
-    UniversalPrinter<internal::string>::Print(regex_->pattern(), os);
-  }
-
- private:
-  const internal::linked_ptr<const RE> regex_;
-  const bool full_match_;
-
-  GTEST_DISALLOW_ASSIGN_(MatchesRegexMatcher);
-};
-
-// Implements a matcher that compares the two fields of a 2-tuple
-// using one of the ==, <=, <, etc, operators.  The two fields being
-// compared don't have to have the same type.
-//
-// The matcher defined here is polymorphic (for example, Eq() can be
-// used to match a tuple<int, short>, a tuple<const long&, double>,
-// etc).  Therefore we use a template type conversion operator in the
-// implementation.
-template <typename D, typename Op>
-class PairMatchBase {
- public:
-  template <typename T1, typename T2>
-  operator Matcher< ::testing::tuple<T1, T2> >() const {
-    return MakeMatcher(new Impl< ::testing::tuple<T1, T2> >);
-  }
-  template <typename T1, typename T2>
-  operator Matcher<const ::testing::tuple<T1, T2>&>() const {
-    return MakeMatcher(new Impl<const ::testing::tuple<T1, T2>&>);
-  }
-
- private:
-  static ::std::ostream& GetDesc(::std::ostream& os) {  // NOLINT
-    return os << D::Desc();
-  }
-
-  template <typename Tuple>
-  class Impl : public MatcherInterface<Tuple> {
-   public:
-    virtual bool MatchAndExplain(
-        Tuple args,
-        MatchResultListener* /* listener */) const {
-      return Op()(::testing::get<0>(args), ::testing::get<1>(args));
-    }
-    virtual void DescribeTo(::std::ostream* os) const {
-      *os << "are " << GetDesc;
-    }
-    virtual void DescribeNegationTo(::std::ostream* os) const {
-      *os << "aren't " << GetDesc;
-    }
-  };
-};
-
-class Eq2Matcher : public PairMatchBase<Eq2Matcher, AnyEq> {
- public:
-  static const char* Desc() { return "an equal pair"; }
-};
-class Ne2Matcher : public PairMatchBase<Ne2Matcher, AnyNe> {
- public:
-  static const char* Desc() { return "an unequal pair"; }
-};
-class Lt2Matcher : public PairMatchBase<Lt2Matcher, AnyLt> {
- public:
-  static const char* Desc() { return "a pair where the first < the second"; }
-};
-class Gt2Matcher : public PairMatchBase<Gt2Matcher, AnyGt> {
- public:
-  static const char* Desc() { return "a pair where the first > the second"; }
-};
-class Le2Matcher : public PairMatchBase<Le2Matcher, AnyLe> {
- public:
-  static const char* Desc() { return "a pair where the first <= the second"; }
-};
-class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> {
- public:
-  static const char* Desc() { return "a pair where the first >= the second"; }
-};
-
-// Implements the Not(...) matcher for a particular argument type T.
-// We do not nest it inside the NotMatcher class template, as that
-// will prevent different instantiations of NotMatcher from sharing
-// the same NotMatcherImpl<T> class.
-template <typename T>
-class NotMatcherImpl : public MatcherInterface<T> {
- public:
-  explicit NotMatcherImpl(const Matcher<T>& matcher)
-      : matcher_(matcher) {}
-
-  virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
-    return !matcher_.MatchAndExplain(x, listener);
-  }
-
-  virtual void DescribeTo(::std::ostream* os) const {
-    matcher_.DescribeNegationTo(os);
-  }
-
-  virtual void DescribeNegationTo(::std::ostream* os) const {
-    matcher_.DescribeTo(os);
-  }
-
- private:
-  const Matcher<T> matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(NotMatcherImpl);
-};
-
-// Implements the Not(m) matcher, which matches a value that doesn't
-// match matcher m.
-template <typename InnerMatcher>
-class NotMatcher {
- public:
-  explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {}
-
-  // This template type conversion operator allows Not(m) to be used
-  // to match any type m can match.
-  template <typename T>
-  operator Matcher<T>() const {
-    return Matcher<T>(new NotMatcherImpl<T>(SafeMatcherCast<T>(matcher_)));
-  }
-
- private:
-  InnerMatcher matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(NotMatcher);
-};
-
-// Implements the AllOf(m1, m2) matcher for a particular argument type
-// T. We do not nest it inside the BothOfMatcher class template, as
-// that will prevent different instantiations of BothOfMatcher from
-// sharing the same BothOfMatcherImpl<T> class.
-template <typename T>
-class BothOfMatcherImpl : public MatcherInterface<T> {
- public:
-  BothOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)
-      : matcher1_(matcher1), matcher2_(matcher2) {}
-
-  virtual void DescribeTo(::std::ostream* os) const {
-    *os << "(";
-    matcher1_.DescribeTo(os);
-    *os << ") and (";
-    matcher2_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual void DescribeNegationTo(::std::ostream* os) const {
-    *os << "(";
-    matcher1_.DescribeNegationTo(os);
-    *os << ") or (";
-    matcher2_.DescribeNegationTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
-    // If either matcher1_ or matcher2_ doesn't match x, we only need
-    // to explain why one of them fails.
-    StringMatchResultListener listener1;
-    if (!matcher1_.MatchAndExplain(x, &listener1)) {
-      *listener << listener1.str();
-      return false;
-    }
-
-    StringMatchResultListener listener2;
-    if (!matcher2_.MatchAndExplain(x, &listener2)) {
-      *listener << listener2.str();
-      return false;
-    }
-
-    // Otherwise we need to explain why *both* of them match.
-    const internal::string s1 = listener1.str();
-    const internal::string s2 = listener2.str();
-
-    if (s1 == "") {
-      *listener << s2;
-    } else {
-      *listener << s1;
-      if (s2 != "") {
-        *listener << ", and " << s2;
-      }
-    }
-    return true;
-  }
-
- private:
-  const Matcher<T> matcher1_;
-  const Matcher<T> matcher2_;
-
-  GTEST_DISALLOW_ASSIGN_(BothOfMatcherImpl);
-};
-
-#if GTEST_LANG_CXX11
-// MatcherList provides mechanisms for storing a variable number of matchers in
-// a list structure (ListType) and creating a combining matcher from such a
-// list.
-// The template is defined recursively using the following template paramters:
-//   * kSize is the length of the MatcherList.
-//   * Head is the type of the first matcher of the list.
-//   * Tail denotes the types of the remaining matchers of the list.
-template <int kSize, typename Head, typename... Tail>
-struct MatcherList {
-  typedef MatcherList<kSize - 1, Tail...> MatcherListTail;
-  typedef ::std::pair<Head, typename MatcherListTail::ListType> ListType;
-
-  // BuildList stores variadic type values in a nested pair structure.
-  // Example:
-  // MatcherList<3, int, string, float>::BuildList(5, "foo", 2.0) will return
-  // the corresponding result of type pair<int, pair<string, float>>.
-  static ListType BuildList(const Head& matcher, const Tail&... tail) {
-    return ListType(matcher, MatcherListTail::BuildList(tail...));
-  }
-
-  // CreateMatcher<T> creates a Matcher<T> from a given list of matchers (built
-  // by BuildList()). CombiningMatcher<T> is used to combine the matchers of the
-  // list. CombiningMatcher<T> must implement MatcherInterface<T> and have a
-  // constructor taking two Matcher<T>s as input.
-  template <typename T, template <typename /* T */> class CombiningMatcher>
-  static Matcher<T> CreateMatcher(const ListType& matchers) {
-    return Matcher<T>(new CombiningMatcher<T>(
-        SafeMatcherCast<T>(matchers.first),
-        MatcherListTail::template CreateMatcher<T, CombiningMatcher>(
-            matchers.second)));
-  }
-};
-
-// The following defines the base case for the recursive definition of
-// MatcherList.
-template <typename Matcher1, typename Matcher2>
-struct MatcherList<2, Matcher1, Matcher2> {
-  typedef ::std::pair<Matcher1, Matcher2> ListType;
-
-  static ListType BuildList(const Matcher1& matcher1,
-                            const Matcher2& matcher2) {
-    return ::std::pair<Matcher1, Matcher2>(matcher1, matcher2);
-  }
-
-  template <typename T, template <typename /* T */> class CombiningMatcher>
-  static Matcher<T> CreateMatcher(const ListType& matchers) {
-    return Matcher<T>(new CombiningMatcher<T>(
-        SafeMatcherCast<T>(matchers.first),
-        SafeMatcherCast<T>(matchers.second)));
-  }
-};
-
-// VariadicMatcher is used for the variadic implementation of
-// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...).
-// CombiningMatcher<T> is used to recursively combine the provided matchers
-// (of type Args...).
-template <template <typename T> class CombiningMatcher, typename... Args>
-class VariadicMatcher {
- public:
-  VariadicMatcher(const Args&... matchers)  // NOLINT
-      : matchers_(MatcherListType::BuildList(matchers...)) {}
-
-  // This template type conversion operator allows an
-  // VariadicMatcher<Matcher1, Matcher2...> object to match any type that
-  // all of the provided matchers (Matcher1, Matcher2, ...) can match.
-  template <typename T>
-  operator Matcher<T>() const {
-    return MatcherListType::template CreateMatcher<T, CombiningMatcher>(
-        matchers_);
-  }
-
- private:
-  typedef MatcherList<sizeof...(Args), Args...> MatcherListType;
-
-  const typename MatcherListType::ListType matchers_;
-
-  GTEST_DISALLOW_ASSIGN_(VariadicMatcher);
-};
-
-template <typename... Args>
-using AllOfMatcher = VariadicMatcher<BothOfMatcherImpl, Args...>;
-
-#endif  // GTEST_LANG_CXX11
-
-// Used for implementing the AllOf(m_1, ..., m_n) matcher, which
-// matches a value that matches all of the matchers m_1, ..., and m_n.
-template <typename Matcher1, typename Matcher2>
-class BothOfMatcher {
- public:
-  BothOfMatcher(Matcher1 matcher1, Matcher2 matcher2)
-      : matcher1_(matcher1), matcher2_(matcher2) {}
-
-  // This template type conversion operator allows a
-  // BothOfMatcher<Matcher1, Matcher2> object to match any type that
-  // both Matcher1 and Matcher2 can match.
-  template <typename T>
-  operator Matcher<T>() const {
-    return Matcher<T>(new BothOfMatcherImpl<T>(SafeMatcherCast<T>(matcher1_),
-                                               SafeMatcherCast<T>(matcher2_)));
-  }
-
- private:
-  Matcher1 matcher1_;
-  Matcher2 matcher2_;
-
-  GTEST_DISALLOW_ASSIGN_(BothOfMatcher);
-};
-
-// Implements the AnyOf(m1, m2) matcher for a particular argument type
-// T.  We do not nest it inside the AnyOfMatcher class template, as
-// that will prevent different instantiations of AnyOfMatcher from
-// sharing the same EitherOfMatcherImpl<T> class.
-template <typename T>
-class EitherOfMatcherImpl : public MatcherInterface<T> {
- public:
-  EitherOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)
-      : matcher1_(matcher1), matcher2_(matcher2) {}
-
-  virtual void DescribeTo(::std::ostream* os) const {
-    *os << "(";
-    matcher1_.DescribeTo(os);
-    *os << ") or (";
-    matcher2_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual void DescribeNegationTo(::std::ostream* os) const {
-    *os << "(";
-    matcher1_.DescribeNegationTo(os);
-    *os << ") and (";
-    matcher2_.DescribeNegationTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
-    // If either matcher1_ or matcher2_ matches x, we just need to
-    // explain why *one* of them matches.
-    StringMatchResultListener listener1;
-    if (matcher1_.MatchAndExplain(x, &listener1)) {
-      *listener << listener1.str();
-      return true;
-    }
-
-    StringMatchResultListener listener2;
-    if (matcher2_.MatchAndExplain(x, &listener2)) {
-      *listener << listener2.str();
-      return true;
-    }
-
-    // Otherwise we need to explain why *both* of them fail.
-    const internal::string s1 = listener1.str();
-    const internal::string s2 = listener2.str();
-
-    if (s1 == "") {
-      *listener << s2;
-    } else {
-      *listener << s1;
-      if (s2 != "") {
-        *listener << ", and " << s2;
-      }
-    }
-    return false;
-  }
-
- private:
-  const Matcher<T> matcher1_;
-  const Matcher<T> matcher2_;
-
-  GTEST_DISALLOW_ASSIGN_(EitherOfMatcherImpl);
-};
-
-#if GTEST_LANG_CXX11
-// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...).
-template <typename... Args>
-using AnyOfMatcher = VariadicMatcher<EitherOfMatcherImpl, Args...>;
-
-#endif  // GTEST_LANG_CXX11
-
-// Used for implementing the AnyOf(m_1, ..., m_n) matcher, which
-// matches a value that matches at least one of the matchers m_1, ...,
-// and m_n.
-template <typename Matcher1, typename Matcher2>
-class EitherOfMatcher {
- public:
-  EitherOfMatcher(Matcher1 matcher1, Matcher2 matcher2)
-      : matcher1_(matcher1), matcher2_(matcher2) {}
-
-  // This template type conversion operator allows a
-  // EitherOfMatcher<Matcher1, Matcher2> object to match any type that
-  // both Matcher1 and Matcher2 can match.
-  template <typename T>
-  operator Matcher<T>() const {
-    return Matcher<T>(new EitherOfMatcherImpl<T>(
-        SafeMatcherCast<T>(matcher1_), SafeMatcherCast<T>(matcher2_)));
-  }
-
- private:
-  Matcher1 matcher1_;
-  Matcher2 matcher2_;
-
-  GTEST_DISALLOW_ASSIGN_(EitherOfMatcher);
-};
-
-// Used for implementing Truly(pred), which turns a predicate into a
-// matcher.
-template <typename Predicate>
-class TrulyMatcher {
- public:
-  explicit TrulyMatcher(Predicate pred) : predicate_(pred) {}
-
-  // This method template allows Truly(pred) to be used as a matcher
-  // for type T where T is the argument type of predicate 'pred'.  The
-  // argument is passed by reference as the predicate may be
-  // interested in the address of the argument.
-  template <typename T>
-  bool MatchAndExplain(T& x,  // NOLINT
-                       MatchResultListener* /* listener */) const {
-    // Without the if-statement, MSVC sometimes warns about converting
-    // a value to bool (warning 4800).
-    //
-    // We cannot write 'return !!predicate_(x);' as that doesn't work
-    // when predicate_(x) returns a class convertible to bool but
-    // having no operator!().
-    if (predicate_(x))
-      return true;
-    return false;
-  }
-
-  void DescribeTo(::std::ostream* os) const {
-    *os << "satisfies the given predicate";
-  }
-
-  void DescribeNegationTo(::std::ostream* os) const {
-    *os << "doesn't satisfy the given predicate";
-  }
-
- private:
-  Predicate predicate_;
-
-  GTEST_DISALLOW_ASSIGN_(TrulyMatcher);
-};
-
-// Used for implementing Matches(matcher), which turns a matcher into
-// a predicate.
-template <typename M>
-class MatcherAsPredicate {
- public:
-  explicit MatcherAsPredicate(M matcher) : matcher_(matcher) {}
-
-  // This template operator() allows Matches(m) to be used as a
-  // predicate on type T where m is a matcher on type T.
-  //
-  // The argument x is passed by reference instead of by value, as
-  // some matcher may be interested in its address (e.g. as in
-  // Matches(Ref(n))(x)).
-  template <typename T>
-  bool operator()(const T& x) const {
-    // We let matcher_ commit to a particular type here instead of
-    // when the MatcherAsPredicate object was constructed.  This
-    // allows us to write Matches(m) where m is a polymorphic matcher
-    // (e.g. Eq(5)).
-    //
-    // If we write Matcher<T>(matcher_).Matches(x) here, it won't
-    // compile when matcher_ has type Matcher<const T&>; if we write
-    // Matcher<const T&>(matcher_).Matches(x) here, it won't compile
-    // when matcher_ has type Matcher<T>; if we just write
-    // matcher_.Matches(x), it won't compile when matcher_ is
-    // polymorphic, e.g. Eq(5).
-    //
-    // MatcherCast<const T&>() is necessary for making the code work
-    // in all of the above situations.
-    return MatcherCast<const T&>(matcher_).Matches(x);
-  }
-
- private:
-  M matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(MatcherAsPredicate);
-};
-
-// For implementing ASSERT_THAT() and EXPECT_THAT().  The template
-// argument M must be a type that can be converted to a matcher.
-template <typename M>
-class PredicateFormatterFromMatcher {
- public:
-  explicit PredicateFormatterFromMatcher(M m) : matcher_(internal::move(m)) {}
-
-  // This template () operator allows a PredicateFormatterFromMatcher
-  // object to act as a predicate-formatter suitable for using with
-  // Google Test's EXPECT_PRED_FORMAT1() macro.
-  template <typename T>
-  AssertionResult operator()(const char* value_text, const T& x) const {
-    // We convert matcher_ to a Matcher<const T&> *now* instead of
-    // when the PredicateFormatterFromMatcher object was constructed,
-    // as matcher_ may be polymorphic (e.g. NotNull()) and we won't
-    // know which type to instantiate it to until we actually see the
-    // type of x here.
-    //
-    // We write SafeMatcherCast<const T&>(matcher_) instead of
-    // Matcher<const T&>(matcher_), as the latter won't compile when
-    // matcher_ has type Matcher<T> (e.g. An<int>()).
-    // We don't write MatcherCast<const T&> either, as that allows
-    // potentially unsafe downcasting of the matcher argument.
-    const Matcher<const T&> matcher = SafeMatcherCast<const T&>(matcher_);
-    StringMatchResultListener listener;
-    if (MatchPrintAndExplain(x, matcher, &listener))
-      return AssertionSuccess();
-
-    ::std::stringstream ss;
-    ss << "Value of: " << value_text << "\n"
-       << "Expected: ";
-    matcher.DescribeTo(&ss);
-    ss << "\n  Actual: " << listener.str();
-    return AssertionFailure() << ss.str();
-  }
-
- private:
-  const M matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(PredicateFormatterFromMatcher);
-};
-
-// A helper function for converting a matcher to a predicate-formatter
-// without the user needing to explicitly write the type.  This is
-// used for implementing ASSERT_THAT() and EXPECT_THAT().
-// Implementation detail: 'matcher' is received by-value to force decaying.
-template <typename M>
-inline PredicateFormatterFromMatcher<M>
-MakePredicateFormatterFromMatcher(M matcher) {
-  return PredicateFormatterFromMatcher<M>(internal::move(matcher));
-}
-
-// Implements the polymorphic floating point equality matcher, which matches
-// two float values using ULP-based approximation or, optionally, a
-// user-specified epsilon.  The template is meant to be instantiated with
-// FloatType being either float or double.
-template <typename FloatType>
-class FloatingEqMatcher {
- public:
-  // Constructor for FloatingEqMatcher.
-  // The matcher's input will be compared with expected.  The matcher treats two
-  // NANs as equal if nan_eq_nan is true.  Otherwise, under IEEE standards,
-  // equality comparisons between NANs will always return false.  We specify a
-  // negative max_abs_error_ term to indicate that ULP-based approximation will
-  // be used for comparison.
-  FloatingEqMatcher(FloatType expected, bool nan_eq_nan) :
-    expected_(expected), nan_eq_nan_(nan_eq_nan), max_abs_error_(-1) {
-  }
-
-  // Constructor that supports a user-specified max_abs_error that will be used
-  // for comparison instead of ULP-based approximation.  The max absolute
-  // should be non-negative.
-  FloatingEqMatcher(FloatType expected, bool nan_eq_nan,
-                    FloatType max_abs_error)
-      : expected_(expected),
-        nan_eq_nan_(nan_eq_nan),
-        max_abs_error_(max_abs_error) {
-    GTEST_CHECK_(max_abs_error >= 0)
-        << ", where max_abs_error is" << max_abs_error;
-  }
-
-  // Implements floating point equality matcher as a Matcher<T>.
-  template <typename T>
-  class Impl : public MatcherInterface<T> {
-   public:
-    Impl(FloatType expected, bool nan_eq_nan, FloatType max_abs_error)
-        : expected_(expected),
-          nan_eq_nan_(nan_eq_nan),
-          max_abs_error_(max_abs_error) {}
-
-    virtual bool MatchAndExplain(T value,
-                                 MatchResultListener* listener) const {
-      const FloatingPoint<FloatType> actual(value), expected(expected_);
-
-      // Compares NaNs first, if nan_eq_nan_ is true.
-      if (actual.is_nan() || expected.is_nan()) {
-        if (actual.is_nan() && expected.is_nan()) {
-          return nan_eq_nan_;
-        }
-        // One is nan; the other is not nan.
-        return false;
-      }
-      if (HasMaxAbsError()) {
-        // We perform an equality check so that inf will match inf, regardless
-        // of error bounds.  If the result of value - expected_ would result in
-        // overflow or if either value is inf, the default result is infinity,
-        // which should only match if max_abs_error_ is also infinity.
-        if (value == expected_) {
-          return true;
-        }
-
-        const FloatType diff = value - expected_;
-        if (fabs(diff) <= max_abs_error_) {
-          return true;
-        }
-
-        if (listener->IsInterested()) {
-          *listener << "which is " << diff << " from " << expected_;
-        }
-        return false;
-      } else {
-        return actual.AlmostEquals(expected);
-      }
-    }
-
-    virtual void DescribeTo(::std::ostream* os) const {
-      // os->precision() returns the previously set precision, which we
-      // store to restore the ostream to its original configuration
-      // after outputting.
-      const ::std::streamsize old_precision = os->precision(
-          ::std::numeric_limits<FloatType>::digits10 + 2);
-      if (FloatingPoint<FloatType>(expected_).is_nan()) {
-        if (nan_eq_nan_) {
-          *os << "is NaN";
-        } else {
-          *os << "never matches";
-        }
-      } else {
-        *os << "is approximately " << expected_;
-        if (HasMaxAbsError()) {
-          *os << " (absolute error <= " << max_abs_error_ << ")";
-        }
-      }
-      os->precision(old_precision);
-    }
-
-    virtual void DescribeNegationTo(::std::ostream* os) const {
-      // As before, get original precision.
-      const ::std::streamsize old_precision = os->precision(
-          ::std::numeric_limits<FloatType>::digits10 + 2);
-      if (FloatingPoint<FloatType>(expected_).is_nan()) {
-        if (nan_eq_nan_) {
-          *os << "isn't NaN";
-        } else {
-          *os << "is anything";
-        }
-      } else {
-        *os << "isn't approximately " << expected_;
-        if (HasMaxAbsError()) {
-          *os << " (absolute error > " << max_abs_error_ << ")";
-        }
-      }
-      // Restore original precision.
-      os->precision(old_precision);
-    }
-
-   private:
-    bool HasMaxAbsError() const {
-      return max_abs_error_ >= 0;
-    }
-
-    const FloatType expected_;
-    const bool nan_eq_nan_;
-    // max_abs_error will be used for value comparison when >= 0.
-    const FloatType max_abs_error_;
-
-    GTEST_DISALLOW_ASSIGN_(Impl);
-  };
-
-  // The following 3 type conversion operators allow FloatEq(expected) and
-  // NanSensitiveFloatEq(expected) to be used as a Matcher<float>, a
-  // Matcher<const float&>, or a Matcher<float&>, but nothing else.
-  // (While Google's C++ coding style doesn't allow arguments passed
-  // by non-const reference, we may see them in code not conforming to
-  // the style.  Therefore Google Mock needs to support them.)
-  operator Matcher<FloatType>() const {
-    return MakeMatcher(
-        new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_));
-  }
-
-  operator Matcher<const FloatType&>() const {
-    return MakeMatcher(
-        new Impl<const FloatType&>(expected_, nan_eq_nan_, max_abs_error_));
-  }
-
-  operator Matcher<FloatType&>() const {
-    return MakeMatcher(
-        new Impl<FloatType&>(expected_, nan_eq_nan_, max_abs_error_));
-  }
-
- private:
-  const FloatType expected_;
-  const bool nan_eq_nan_;
-  // max_abs_error will be used for value comparison when >= 0.
-  const FloatType max_abs_error_;
-
-  GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher);
-};
-
-// Implements the Pointee(m) matcher for matching a pointer whose
-// pointee matches matcher m.  The pointer can be either raw or smart.
-template <typename InnerMatcher>
-class PointeeMatcher {
- public:
-  explicit PointeeMatcher(const InnerMatcher& matcher) : matcher_(matcher) {}
-
-  // This type conversion operator template allows Pointee(m) to be
-  // used as a matcher for any pointer type whose pointee type is
-  // compatible with the inner matcher, where type Pointer can be
-  // either a raw pointer or a smart pointer.
-  //
-  // The reason we do this instead of relying on
-  // MakePolymorphicMatcher() is that the latter is not flexible
-  // enough for implementing the DescribeTo() method of Pointee().
-  template <typename Pointer>
-  operator Matcher<Pointer>() const {
-    return MakeMatcher(new Impl<Pointer>(matcher_));
-  }
-
- private:
-  // The monomorphic implementation that works for a particular pointer type.
-  template <typename Pointer>
-  class Impl : public MatcherInterface<Pointer> {
-   public:
-    typedef typename PointeeOf<GTEST_REMOVE_CONST_(  // NOLINT
-        GTEST_REMOVE_REFERENCE_(Pointer))>::type Pointee;
-
-    explicit Impl(const InnerMatcher& matcher)
-        : matcher_(MatcherCast<const Pointee&>(matcher)) {}
-
-    virtual void DescribeTo(::std::ostream* os) const {
-      *os << "points to a value that ";
-      matcher_.DescribeTo(os);
-    }
-
-    virtual void DescribeNegationTo(::std::ostream* os) const {
-      *os << "does not point to a value that ";
-      matcher_.DescribeTo(os);
-    }
-
-    virtual bool MatchAndExplain(Pointer pointer,
-                                 MatchResultListener* listener) const {
-      if (GetRawPointer(pointer) == NULL)
-        return false;
-
-      *listener << "which points to ";
-      return MatchPrintAndExplain(*pointer, matcher_, listener);
-    }
-
-   private:
-    const Matcher<const Pointee&> matcher_;
-
-    GTEST_DISALLOW_ASSIGN_(Impl);
-  };
-
-  const InnerMatcher matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(PointeeMatcher);
-};
-
-// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or
-// reference that matches inner_matcher when dynamic_cast<T> is applied.
-// The result of dynamic_cast<To> is forwarded to the inner matcher.
-// If To is a pointer and the cast fails, the inner matcher will receive NULL.
-// If To is a reference and the cast fails, this matcher returns false
-// immediately.
-template <typename To>
-class WhenDynamicCastToMatcherBase {
- public:
-  explicit WhenDynamicCastToMatcherBase(const Matcher<To>& matcher)
-      : matcher_(matcher) {}
-
-  void DescribeTo(::std::ostream* os) const {
-    GetCastTypeDescription(os);
-    matcher_.DescribeTo(os);
-  }
-
-  void DescribeNegationTo(::std::ostream* os) const {
-    GetCastTypeDescription(os);
-    matcher_.DescribeNegationTo(os);
-  }
-
- protected:
-  const Matcher<To> matcher_;
-
-  static string GetToName() {
-#if GTEST_HAS_RTTI
-    return GetTypeName<To>();
-#else  // GTEST_HAS_RTTI
-    return "the target type";
-#endif  // GTEST_HAS_RTTI
-  }
-
- private:
-  static void GetCastTypeDescription(::std::ostream* os) {
-    *os << "when dynamic_cast to " << GetToName() << ", ";
-  }
-
-  GTEST_DISALLOW_ASSIGN_(WhenDynamicCastToMatcherBase);
-};
-
-// Primary template.
-// To is a pointer. Cast and forward the result.
-template <typename To>
-class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> {
- public:
-  explicit WhenDynamicCastToMatcher(const Matcher<To>& matcher)
-      : WhenDynamicCastToMatcherBase<To>(matcher) {}
-
-  template <typename From>
-  bool MatchAndExplain(From from, MatchResultListener* listener) const {
-    // TODO(sbenza): Add more detail on failures. ie did the dyn_cast fail?
-    To to = dynamic_cast<To>(from);
-    return MatchPrintAndExplain(to, this->matcher_, listener);
-  }
-};
-
-// Specialize for references.
-// In this case we return false if the dynamic_cast fails.
-template <typename To>
-class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> {
- public:
-  explicit WhenDynamicCastToMatcher(const Matcher<To&>& matcher)
-      : WhenDynamicCastToMatcherBase<To&>(matcher) {}
-
-  template <typename From>
-  bool MatchAndExplain(From& from, MatchResultListener* listener) const {
-    // We don't want an std::bad_cast here, so do the cast with pointers.
-    To* to = dynamic_cast<To*>(&from);
-    if (to == NULL) {
-      *listener << "which cannot be dynamic_cast to " << this->GetToName();
-      return false;
-    }
-    return MatchPrintAndExplain(*to, this->matcher_, listener);
-  }
-};
-
-// Implements the Field() matcher for matching a field (i.e. member
-// variable) of an object.
-template <typename Class, typename FieldType>
-class FieldMatcher {
- public:
-  FieldMatcher(FieldType Class::*field,
-               const Matcher<const FieldType&>& matcher)
-      : field_(field), matcher_(matcher) {}
-
-  void DescribeTo(::std::ostream* os) const {
-    *os << "is an object whose given field ";
-    matcher_.DescribeTo(os);
-  }
-
-  void DescribeNegationTo(::std::ostream* os) const {
-    *os << "is an object whose given field ";
-    matcher_.DescribeNegationTo(os);
-  }
-
-  template <typename T>
-  bool MatchAndExplain(const T& value, MatchResultListener* listener) const {
-    return MatchAndExplainImpl(
-        typename ::testing::internal::
-            is_pointer<GTEST_REMOVE_CONST_(T)>::type(),
-        value, listener);
-  }
-
- private:
-  // The first argument of MatchAndExplainImpl() is needed to help
-  // Symbian's C++ compiler choose which overload to use.  Its type is
-  // true_type iff the Field() matcher is used to match a pointer.
-  bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj,
-                           MatchResultListener* listener) const {
-    *listener << "whose given field is ";
-    return MatchPrintAndExplain(obj.*field_, matcher_, listener);
-  }
-
-  bool MatchAndExplainImpl(true_type /* is_pointer */, const Class* p,
-                           MatchResultListener* listener) const {
-    if (p == NULL)
-      return false;
-
-    *listener << "which points to an object ";
-    // Since *p has a field, it must be a class/struct/union type and
-    // thus cannot be a pointer.  Therefore we pass false_type() as
-    // the first argument.
-    return MatchAndExplainImpl(false_type(), *p, listener);
-  }
-
-  const FieldType Class::*field_;
-  const Matcher<const FieldType&> matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(FieldMatcher);
-};
-
-// Implements the Property() matcher for matching a property
-// (i.e. return value of a getter method) of an object.
-template <typename Class, typename PropertyType>
-class PropertyMatcher {
- public:
-  // The property may have a reference type, so 'const PropertyType&'
-  // may cause double references and fail to compile.  That's why we
-  // need GTEST_REFERENCE_TO_CONST, which works regardless of
-  // PropertyType being a reference or not.
-  typedef GTEST_REFERENCE_TO_CONST_(PropertyType) RefToConstProperty;
-
-  PropertyMatcher(PropertyType (Class::*property)() const,
-                  const Matcher<RefToConstProperty>& matcher)
-      : property_(property), matcher_(matcher) {}
-
-  void DescribeTo(::std::ostream* os) const {
-    *os << "is an object whose given property ";
-    matcher_.DescribeTo(os);
-  }
-
-  void DescribeNegationTo(::std::ostream* os) const {
-    *os << "is an object whose given property ";
-    matcher_.DescribeNegationTo(os);
-  }
-
-  template <typename T>
-  bool MatchAndExplain(const T&value, MatchResultListener* listener) const {
-    return MatchAndExplainImpl(
-        typename ::testing::internal::
-            is_pointer<GTEST_REMOVE_CONST_(T)>::type(),
-        value, listener);
-  }
-
- private:
-  // The first argument of MatchAndExplainImpl() is needed to help
-  // Symbian's C++ compiler choose which overload to use.  Its type is
-  // true_type iff the Property() matcher is used to match a pointer.
-  bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj,
-                           MatchResultListener* listener) const {
-    *listener << "whose given property is ";
-    // Cannot pass the return value (for example, int) to MatchPrintAndExplain,
-    // which takes a non-const reference as argument.
-#if defined(_PREFAST_ ) && _MSC_VER == 1800
-    // Workaround bug in VC++ 2013's /analyze parser.
-    // https://connect.microsoft.com/VisualStudio/feedback/details/1106363/internal-compiler-error-with-analyze-due-to-failure-to-infer-move
-    posix::Abort();  // To make sure it is never run.
-    return false;
-#else
-    RefToConstProperty result = (obj.*property_)();
-    return MatchPrintAndExplain(result, matcher_, listener);
-#endif
-  }
-
-  bool MatchAndExplainImpl(true_type /* is_pointer */, const Class* p,
-                           MatchResultListener* listener) const {
-    if (p == NULL)
-      return false;
-
-    *listener << "which points to an object ";
-    // Since *p has a property method, it must be a class/struct/union
-    // type and thus cannot be a pointer.  Therefore we pass
-    // false_type() as the first argument.
-    return MatchAndExplainImpl(false_type(), *p, listener);
-  }
-
-  PropertyType (Class::*property_)() const;
-  const Matcher<RefToConstProperty> matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(PropertyMatcher);
-};
-
-// Type traits specifying various features of different functors for ResultOf.
-// The default template specifies features for functor objects.
-// Functor classes have to typedef argument_type and result_type
-// to be compatible with ResultOf.
-template <typename Functor>
-struct CallableTraits {
-  typedef typename Functor::result_type ResultType;
-  typedef Functor StorageType;
-
-  static void CheckIsValid(Functor /* functor */) {}
-  template <typename T>
-  static ResultType Invoke(Functor f, T arg) { return f(arg); }
-};
-
-// Specialization for function pointers.
-template <typename ArgType, typename ResType>
-struct CallableTraits<ResType(*)(ArgType)> {
-  typedef ResType ResultType;
-  typedef ResType(*StorageType)(ArgType);
-
-  static void CheckIsValid(ResType(*f)(ArgType)) {
-    GTEST_CHECK_(f != NULL)
-        << "NULL function pointer is passed into ResultOf().";
-  }
-  template <typename T>
-  static ResType Invoke(ResType(*f)(ArgType), T arg) {
-    return (*f)(arg);
-  }
-};
-
-// Implements the ResultOf() matcher for matching a return value of a
-// unary function of an object.
-template <typename Callable>
-class ResultOfMatcher {
- public:
-  typedef typename CallableTraits<Callable>::ResultType ResultType;
-
-  ResultOfMatcher(Callable callable, const Matcher<ResultType>& matcher)
-      : callable_(callable), matcher_(matcher) {
-    CallableTraits<Callable>::CheckIsValid(callable_);
-  }
-
-  template <typename T>
-  operator Matcher<T>() const {
-    return Matcher<T>(new Impl<T>(callable_, matcher_));
-  }
-
- private:
-  typedef typename CallableTraits<Callable>::StorageType CallableStorageType;
-
-  template <typename T>
-  class Impl : public MatcherInterface<T> {
-   public:
-    Impl(CallableStorageType callable, const Matcher<ResultType>& matcher)
-        : callable_(callable), matcher_(matcher) {}
-
-    virtual void DescribeTo(::std::ostream* os) const {
-      *os << "is mapped by the given callable to a value that ";
-      matcher_.DescribeTo(os);
-    }
-
-    virtual void DescribeNegationTo(::std::ostream* os) const {
-      *os << "is mapped by the given callable to a value that ";
-      matcher_.DescribeNegationTo(os);
-    }
-
-    virtual bool MatchAndExplain(T obj, MatchResultListener* listener) const {
-      *listener << "which is mapped by the given callable to ";
-      // Cannot pass the return value (for example, int) to
-      // MatchPrintAndExplain, which takes a non-const reference as argument.
-      ResultType result =
-          CallableTraits<Callable>::template Invoke<T>(callable_, obj);
-      return MatchPrintAndExplain(result, matcher_, listener);
-    }
-
-   private:
-    // Functors often define operator() as non-const method even though
-    // they are actualy stateless. But we need to use them even when
-    // 'this' is a const pointer. It's the user's responsibility not to
-    // use stateful callables with ResultOf(), which does't guarantee
-    // how many times the callable will be invoked.
-    mutable CallableStorageType callable_;
-    const Matcher<ResultType> matcher_;
-
-    GTEST_DISALLOW_ASSIGN_(Impl);
-  };  // class Impl
-
-  const CallableStorageType callable_;
-  const Matcher<ResultType> matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(ResultOfMatcher);
-};
-
-// Implements a matcher that checks the size of an STL-style container.
-template <typename SizeMatcher>
-class SizeIsMatcher {
- public:
-  explicit SizeIsMatcher(const SizeMatcher& size_matcher)
-       : size_matcher_(size_matcher) {
-  }
-
-  template <typename Container>
-  operator Matcher<Container>() const {
-    return MakeMatcher(new Impl<Container>(size_matcher_));
-  }
-
-  template <typename Container>
-  class Impl : public MatcherInterface<Container> {
-   public:
-    typedef internal::StlContainerView<
-         GTEST_REMOVE_REFERENCE_AND_CONST_(Container)> ContainerView;
-    typedef typename ContainerView::type::size_type SizeType;
-    explicit Impl(const SizeMatcher& size_matcher)
-        : size_matcher_(MatcherCast<SizeType>(size_matcher)) {}
-
-    virtual void DescribeTo(::std::ostream* os) const {
-      *os << "size ";
-      size_matcher_.DescribeTo(os);
-    }
-    virtual void DescribeNegationTo(::std::ostream* os) const {
-      *os << "size ";
-      size_matcher_.DescribeNegationTo(os);
-    }
-
-    virtual bool MatchAndExplain(Container container,
-                                 MatchResultListener* listener) const {
-      SizeType size = container.size();
-      StringMatchResultListener size_listener;
-      const bool result = size_matcher_.MatchAndExplain(size, &size_listener);
-      *listener
-          << "whose size " << size << (result ? " matches" : " doesn't match");
-      PrintIfNotEmpty(size_listener.str(), listener->stream());
-      return result;
-    }
-
-   private:
-    const Matcher<SizeType> size_matcher_;
-    GTEST_DISALLOW_ASSIGN_(Impl);
-  };
-
- private:
-  const SizeMatcher size_matcher_;
-  GTEST_DISALLOW_ASSIGN_(SizeIsMatcher);
-};
-
-// Implements a matcher that checks the begin()..end() distance of an STL-style
-// container.
-template <typename DistanceMatcher>
-class BeginEndDistanceIsMatcher {
- public:
-  explicit BeginEndDistanceIsMatcher(const DistanceMatcher& distance_matcher)
-      : distance_matcher_(distance_matcher) {}
-
-  template <typename Container>
-  operator Matcher<Container>() const {
-    return MakeMatcher(new Impl<Container>(distance_matcher_));
-  }
-
-  template <typename Container>
-  class Impl : public MatcherInterface<Container> {
-   public:
-    typedef internal::StlContainerView<
-        GTEST_REMOVE_REFERENCE_AND_CONST_(Container)> ContainerView;
-    typedef typename std::iterator_traits<
-        typename ContainerView::type::const_iterator>::difference_type
-        DistanceType;
-    explicit Impl(const DistanceMatcher& distance_matcher)
-        : distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {}
-
-    virtual void DescribeTo(::std::ostream* os) const {
-      *os << "distance between begin() and end() ";
-      distance_matcher_.DescribeTo(os);
-    }
-    virtual void DescribeNegationTo(::std::ostream* os) const {
-      *os << "distance between begin() and end() ";
-      distance_matcher_.DescribeNegationTo(os);
-    }
-
-    virtual bool MatchAndExplain(Container container,
-                                 MatchResultListener* listener) const {
-#if GTEST_HAS_STD_BEGIN_AND_END_
-      using std::begin;
-      using std::end;
-      DistanceType distance = std::distance(begin(container), end(container));
-#else
-      DistanceType distance = std::distance(container.begin(), container.end());
-#endif
-      StringMatchResultListener distance_listener;
-      const bool result =
-          distance_matcher_.MatchAndExplain(distance, &distance_listener);
-      *listener << "whose distance between begin() and end() " << distance
-                << (result ? " matches" : " doesn't match");
-      PrintIfNotEmpty(distance_listener.str(), listener->stream());
-      return result;
-    }
-
-   private:
-    const Matcher<DistanceType> distance_matcher_;
-    GTEST_DISALLOW_ASSIGN_(Impl);
-  };
-
- private:
-  const DistanceMatcher distance_matcher_;
-  GTEST_DISALLOW_ASSIGN_(BeginEndDistanceIsMatcher);
-};
-
-// Implements an equality matcher for any STL-style container whose elements
-// support ==. This matcher is like Eq(), but its failure explanations provide
-// more detailed information that is useful when the container is used as a set.
-// The failure message reports elements that are in one of the operands but not
-// the other. The failure messages do not report duplicate or out-of-order
-// elements in the containers (which don't properly matter to sets, but can
-// occur if the containers are vectors or lists, for example).
-//
-// Uses the container's const_iterator, value_type, operator ==,
-// begin(), and end().
-template <typename Container>
-class ContainerEqMatcher {
- public:
-  typedef internal::StlContainerView<Container> View;
-  typedef typename View::type StlContainer;
-  typedef typename View::const_reference StlContainerReference;
-
-  // We make a copy of expected in case the elements in it are modified
-  // after this matcher is created.
-  explicit ContainerEqMatcher(const Container& expected)
-      : expected_(View::Copy(expected)) {
-    // Makes sure the user doesn't instantiate this class template
-    // with a const or reference type.
-    (void)testing::StaticAssertTypeEq<Container,
-        GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>();
-  }
-
-  void DescribeTo(::std::ostream* os) const {
-    *os << "equals ";
-    UniversalPrint(expected_, os);
-  }
-  void DescribeNegationTo(::std::ostream* os) const {
-    *os << "does not equal ";
-    UniversalPrint(expected_, os);
-  }
-
-  template <typename LhsContainer>
-  bool MatchAndExplain(const LhsContainer& lhs,
-                       MatchResultListener* listener) const {
-    // GTEST_REMOVE_CONST_() is needed to work around an MSVC 8.0 bug
-    // that causes LhsContainer to be a const type sometimes.
-    typedef internal::StlContainerView<GTEST_REMOVE_CONST_(LhsContainer)>
-        LhsView;
-    typedef typename LhsView::type LhsStlContainer;
-    StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
-    if (lhs_stl_container == expected_)
-      return true;
-
-    ::std::ostream* const os = listener->stream();
-    if (os != NULL) {
-      // Something is different. Check for extra values first.
-      bool printed_header = false;
-      for (typename LhsStlContainer::const_iterator it =
-               lhs_stl_container.begin();
-           it != lhs_stl_container.end(); ++it) {
-        if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) ==
-            expected_.end()) {
-          if (printed_header) {
-            *os << ", ";
-          } else {
-            *os << "which has these unexpected elements: ";
-            printed_header = true;
-          }
-          UniversalPrint(*it, os);
-        }
-      }
-
-      // Now check for missing values.
-      bool printed_header2 = false;
-      for (typename StlContainer::const_iterator it = expected_.begin();
-           it != expected_.end(); ++it) {
-        if (internal::ArrayAwareFind(
-                lhs_stl_container.begin(), lhs_stl_container.end(), *it) ==
-            lhs_stl_container.end()) {
-          if (printed_header2) {
-            *os << ", ";
-          } else {
-            *os << (printed_header ? ",\nand" : "which")
-                << " doesn't have these expected elements: ";
-            printed_header2 = true;
-          }
-          UniversalPrint(*it, os);
-        }
-      }
-    }
-
-    return false;
-  }
-
- private:
-  const StlContainer expected_;
-
-  GTEST_DISALLOW_ASSIGN_(ContainerEqMatcher);
-};
-
-// A comparator functor that uses the < operator to compare two values.
-struct LessComparator {
-  template <typename T, typename U>
-  bool operator()(const T& lhs, const U& rhs) const { return lhs < rhs; }
-};
-
-// Implements WhenSortedBy(comparator, container_matcher).
-template <typename Comparator, typename ContainerMatcher>
-class WhenSortedByMatcher {
- public:
-  WhenSortedByMatcher(const Comparator& comparator,
-                      const ContainerMatcher& matcher)
-      : comparator_(comparator), matcher_(matcher) {}
-
-  template <typename LhsContainer>
-  operator Matcher<LhsContainer>() const {
-    return MakeMatcher(new Impl<LhsContainer>(comparator_, matcher_));
-  }
-
-  template <typename LhsContainer>
-  class Impl : public MatcherInterface<LhsContainer> {
-   public:
-    typedef internal::StlContainerView<
-         GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView;
-    typedef typename LhsView::type LhsStlContainer;
-    typedef typename LhsView::const_reference LhsStlContainerReference;
-    // Transforms std::pair<const Key, Value> into std::pair<Key, Value>
-    // so that we can match associative containers.
-    typedef typename RemoveConstFromKey<
-        typename LhsStlContainer::value_type>::type LhsValue;
-
-    Impl(const Comparator& comparator, const ContainerMatcher& matcher)
-        : comparator_(comparator), matcher_(matcher) {}
-
-    virtual void DescribeTo(::std::ostream* os) const {
-      *os << "(when sorted) ";
-      matcher_.DescribeTo(os);
-    }
-
-    virtual void DescribeNegationTo(::std::ostream* os) const {
-      *os << "(when sorted) ";
-      matcher_.DescribeNegationTo(os);
-    }
-
-    virtual bool MatchAndExplain(LhsContainer lhs,
-                                 MatchResultListener* listener) const {
-      LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
-      ::std::vector<LhsValue> sorted_container(lhs_stl_container.begin(),
-                                               lhs_stl_container.end());
-      ::std::sort(
-           sorted_container.begin(), sorted_container.end(), comparator_);
-
-      if (!listener->IsInterested()) {
-        // If the listener is not interested, we do not need to
-        // construct the inner explanation.
-        return matcher_.Matches(sorted_container);
-      }
-
-      *listener << "which is ";
-      UniversalPrint(sorted_container, listener->stream());
-      *listener << " when sorted";
-
-      StringMatchResultListener inner_listener;
-      const bool match = matcher_.MatchAndExplain(sorted_container,
-                                                  &inner_listener);
-      PrintIfNotEmpty(inner_listener.str(), listener->stream());
-      return match;
-    }
-
-   private:
-    const Comparator comparator_;
-    const Matcher<const ::std::vector<LhsValue>&> matcher_;
-
-    GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl);
-  };
-
- private:
-  const Comparator comparator_;
-  const ContainerMatcher matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(WhenSortedByMatcher);
-};
-
-// Implements Pointwise(tuple_matcher, rhs_container).  tuple_matcher
-// must be able to be safely cast to Matcher<tuple<const T1&, const
-// T2&> >, where T1 and T2 are the types of elements in the LHS
-// container and the RHS container respectively.
-template <typename TupleMatcher, typename RhsContainer>
-class PointwiseMatcher {
- public:
-  typedef internal::StlContainerView<RhsContainer> RhsView;
-  typedef typename RhsView::type RhsStlContainer;
-  typedef typename RhsStlContainer::value_type RhsValue;
-
-  // Like ContainerEq, we make a copy of rhs in case the elements in
-  // it are modified after this matcher is created.
-  PointwiseMatcher(const TupleMatcher& tuple_matcher, const RhsContainer& rhs)
-      : tuple_matcher_(tuple_matcher), rhs_(RhsView::Copy(rhs)) {
-    // Makes sure the user doesn't instantiate this class template
-    // with a const or reference type.
-    (void)testing::StaticAssertTypeEq<RhsContainer,
-        GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>();
-  }
-
-  template <typename LhsContainer>
-  operator Matcher<LhsContainer>() const {
-    return MakeMatcher(new Impl<LhsContainer>(tuple_matcher_, rhs_));
-  }
-
-  template <typename LhsContainer>
-  class Impl : public MatcherInterface<LhsContainer> {
-   public:
-    typedef internal::StlContainerView<
-         GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView;
-    typedef typename LhsView::type LhsStlContainer;
-    typedef typename LhsView::const_reference LhsStlContainerReference;
-    typedef typename LhsStlContainer::value_type LhsValue;
-    // We pass the LHS value and the RHS value to the inner matcher by
-    // reference, as they may be expensive to copy.  We must use tuple
-    // instead of pair here, as a pair cannot hold references (C++ 98,
-    // 20.2.2 [lib.pairs]).
-    typedef ::testing::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg;
-
-    Impl(const TupleMatcher& tuple_matcher, const RhsStlContainer& rhs)
-        // mono_tuple_matcher_ holds a monomorphic version of the tuple matcher.
-        : mono_tuple_matcher_(SafeMatcherCast<InnerMatcherArg>(tuple_matcher)),
-          rhs_(rhs) {}
-
-    virtual void DescribeTo(::std::ostream* os) const {
-      *os << "contains " << rhs_.size()
-          << " values, where each value and its corresponding value in ";
-      UniversalPrinter<RhsStlContainer>::Print(rhs_, os);
-      *os << " ";
-      mono_tuple_matcher_.DescribeTo(os);
-    }
-    virtual void DescribeNegationTo(::std::ostream* os) const {
-      *os << "doesn't contain exactly " << rhs_.size()
-          << " values, or contains a value x at some index i"
-          << " where x and the i-th value of ";
-      UniversalPrint(rhs_, os);
-      *os << " ";
-      mono_tuple_matcher_.DescribeNegationTo(os);
-    }
-
-    virtual bool MatchAndExplain(LhsContainer lhs,
-                                 MatchResultListener* listener) const {
-      LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
-      const size_t actual_size = lhs_stl_container.size();
-      if (actual_size != rhs_.size()) {
-        *listener << "which contains " << actual_size << " values";
-        return false;
-      }
-
-      typename LhsStlContainer::const_iterator left = lhs_stl_container.begin();
-      typename RhsStlContainer::const_iterator right = rhs_.begin();
-      for (size_t i = 0; i != actual_size; ++i, ++left, ++right) {
-        const InnerMatcherArg value_pair(*left, *right);
-
-        if (listener->IsInterested()) {
-          StringMatchResultListener inner_listener;
-          if (!mono_tuple_matcher_.MatchAndExplain(
-                  value_pair, &inner_listener)) {
-            *listener << "where the value pair (";
-            UniversalPrint(*left, listener->stream());
-            *listener << ", ";
-            UniversalPrint(*right, listener->stream());
-            *listener << ") at index #" << i << " don't match";
-            PrintIfNotEmpty(inner_listener.str(), listener->stream());
-            return false;
-          }
-        } else {
-          if (!mono_tuple_matcher_.Matches(value_pair))
-            return false;
-        }
-      }
-
-      return true;
-    }
-
-   private:
-    const Matcher<InnerMatcherArg> mono_tuple_matcher_;
-    const RhsStlContainer rhs_;
-
-    GTEST_DISALLOW_ASSIGN_(Impl);
-  };
-
- private:
-  const TupleMatcher tuple_matcher_;
-  const RhsStlContainer rhs_;
-
-  GTEST_DISALLOW_ASSIGN_(PointwiseMatcher);
-};
-
-// Holds the logic common to ContainsMatcherImpl and EachMatcherImpl.
-template <typename Container>
-class QuantifierMatcherImpl : public MatcherInterface<Container> {
- public:
-  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
-  typedef StlContainerView<RawContainer> View;
-  typedef typename View::type StlContainer;
-  typedef typename View::const_reference StlContainerReference;
-  typedef typename StlContainer::value_type Element;
-
-  template <typename InnerMatcher>
-  explicit QuantifierMatcherImpl(InnerMatcher inner_matcher)
-      : inner_matcher_(
-           testing::SafeMatcherCast<const Element&>(inner_matcher)) {}
-
-  // Checks whether:
-  // * All elements in the container match, if all_elements_should_match.
-  // * Any element in the container matches, if !all_elements_should_match.
-  bool MatchAndExplainImpl(bool all_elements_should_match,
-                           Container container,
-                           MatchResultListener* listener) const {
-    StlContainerReference stl_container = View::ConstReference(container);
-    size_t i = 0;
-    for (typename StlContainer::const_iterator it = stl_container.begin();
-         it != stl_container.end(); ++it, ++i) {
-      StringMatchResultListener inner_listener;
-      const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);
-
-      if (matches != all_elements_should_match) {
-        *listener << "whose element #" << i
-                  << (matches ? " matches" : " doesn't match");
-        PrintIfNotEmpty(inner_listener.str(), listener->stream());
-        return !all_elements_should_match;
-      }
-    }
-    return all_elements_should_match;
-  }
-
- protected:
-  const Matcher<const Element&> inner_matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(QuantifierMatcherImpl);
-};
-
-// Implements Contains(element_matcher) for the given argument type Container.
-// Symmetric to EachMatcherImpl.
-template <typename Container>
-class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> {
- public:
-  template <typename InnerMatcher>
-  explicit ContainsMatcherImpl(InnerMatcher inner_matcher)
-      : QuantifierMatcherImpl<Container>(inner_matcher) {}
-
-  // Describes what this matcher does.
-  virtual void DescribeTo(::std::ostream* os) const {
-    *os << "contains at least one element that ";
-    this->inner_matcher_.DescribeTo(os);
-  }
-
-  virtual void DescribeNegationTo(::std::ostream* os) const {
-    *os << "doesn't contain any element that ";
-    this->inner_matcher_.DescribeTo(os);
-  }
-
-  virtual bool MatchAndExplain(Container container,
-                               MatchResultListener* listener) const {
-    return this->MatchAndExplainImpl(false, container, listener);
-  }
-
- private:
-  GTEST_DISALLOW_ASSIGN_(ContainsMatcherImpl);
-};
-
-// Implements Each(element_matcher) for the given argument type Container.
-// Symmetric to ContainsMatcherImpl.
-template <typename Container>
-class EachMatcherImpl : public QuantifierMatcherImpl<Container> {
- public:
-  template <typename InnerMatcher>
-  explicit EachMatcherImpl(InnerMatcher inner_matcher)
-      : QuantifierMatcherImpl<Container>(inner_matcher) {}
-
-  // Describes what this matcher does.
-  virtual void DescribeTo(::std::ostream* os) const {
-    *os << "only contains elements that ";
-    this->inner_matcher_.DescribeTo(os);
-  }
-
-  virtual void DescribeNegationTo(::std::ostream* os) const {
-    *os << "contains some element that ";
-    this->inner_matcher_.DescribeNegationTo(os);
-  }
-
-  virtual bool MatchAndExplain(Container container,
-                               MatchResultListener* listener) const {
-    return this->MatchAndExplainImpl(true, container, listener);
-  }
-
- private:
-  GTEST_DISALLOW_ASSIGN_(EachMatcherImpl);
-};
-
-// Implements polymorphic Contains(element_matcher).
-template <typename M>
-class ContainsMatcher {
- public:
-  explicit ContainsMatcher(M m) : inner_matcher_(m) {}
-
-  template <typename Container>
-  operator Matcher<Container>() const {
-    return MakeMatcher(new ContainsMatcherImpl<Container>(inner_matcher_));
-  }
-
- private:
-  const M inner_matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(ContainsMatcher);
-};
-
-// Implements polymorphic Each(element_matcher).
-template <typename M>
-class EachMatcher {
- public:
-  explicit EachMatcher(M m) : inner_matcher_(m) {}
-
-  template <typename Container>
-  operator Matcher<Container>() const {
-    return MakeMatcher(new EachMatcherImpl<Container>(inner_matcher_));
-  }
-
- private:
-  const M inner_matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(EachMatcher);
-};
-
-// Implements Key(inner_matcher) for the given argument pair type.
-// Key(inner_matcher) matches an std::pair whose 'first' field matches
-// inner_matcher.  For example, Contains(Key(Ge(5))) can be used to match an
-// std::map that contains at least one element whose key is >= 5.
-template <typename PairType>
-class KeyMatcherImpl : public MatcherInterface<PairType> {
- public:
-  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType;
-  typedef typename RawPairType::first_type KeyType;
-
-  template <typename InnerMatcher>
-  explicit KeyMatcherImpl(InnerMatcher inner_matcher)
-      : inner_matcher_(
-          testing::SafeMatcherCast<const KeyType&>(inner_matcher)) {
-  }
-
-  // Returns true iff 'key_value.first' (the key) matches the inner matcher.
-  virtual bool MatchAndExplain(PairType key_value,
-                               MatchResultListener* listener) const {
-    StringMatchResultListener inner_listener;
-    const bool match = inner_matcher_.MatchAndExplain(key_value.first,
-                                                      &inner_listener);
-    const internal::string explanation = inner_listener.str();
-    if (explanation != "") {
-      *listener << "whose first field is a value " << explanation;
-    }
-    return match;
-  }
-
-  // Describes what this matcher does.
-  virtual void DescribeTo(::std::ostream* os) const {
-    *os << "has a key that ";
-    inner_matcher_.DescribeTo(os);
-  }
-
-  // Describes what the negation of this matcher does.
-  virtual void DescribeNegationTo(::std::ostream* os) const {
-    *os << "doesn't have a key that ";
-    inner_matcher_.DescribeTo(os);
-  }
-
- private:
-  const Matcher<const KeyType&> inner_matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(KeyMatcherImpl);
-};
-
-// Implements polymorphic Key(matcher_for_key).
-template <typename M>
-class KeyMatcher {
- public:
-  explicit KeyMatcher(M m) : matcher_for_key_(m) {}
-
-  template <typename PairType>
-  operator Matcher<PairType>() const {
-    return MakeMatcher(new KeyMatcherImpl<PairType>(matcher_for_key_));
-  }
-
- private:
-  const M matcher_for_key_;
-
-  GTEST_DISALLOW_ASSIGN_(KeyMatcher);
-};
-
-// Implements Pair(first_matcher, second_matcher) for the given argument pair
-// type with its two matchers. See Pair() function below.
-template <typename PairType>
-class PairMatcherImpl : public MatcherInterface<PairType> {
- public:
-  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType;
-  typedef typename RawPairType::first_type FirstType;
-  typedef typename RawPairType::second_type SecondType;
-
-  template <typename FirstMatcher, typename SecondMatcher>
-  PairMatcherImpl(FirstMatcher first_matcher, SecondMatcher second_matcher)
-      : first_matcher_(
-            testing::SafeMatcherCast<const FirstType&>(first_matcher)),
-        second_matcher_(
-            testing::SafeMatcherCast<const SecondType&>(second_matcher)) {
-  }
-
-  // Describes what this matcher does.
-  virtual void DescribeTo(::std::ostream* os) const {
-    *os << "has a first field that ";
-    first_matcher_.DescribeTo(os);
-    *os << ", and has a second field that ";
-    second_matcher_.DescribeTo(os);
-  }
-
-  // Describes what the negation of this matcher does.
-  virtual void DescribeNegationTo(::std::ostream* os) const {
-    *os << "has a first field that ";
-    first_matcher_.DescribeNegationTo(os);
-    *os << ", or has a second field that ";
-    second_matcher_.DescribeNegationTo(os);
-  }
-
-  // Returns true iff 'a_pair.first' matches first_matcher and 'a_pair.second'
-  // matches second_matcher.
-  virtual bool MatchAndExplain(PairType a_pair,
-                               MatchResultListener* listener) const {
-    if (!listener->IsInterested()) {
-      // If the listener is not interested, we don't need to construct the
-      // explanation.
-      return first_matcher_.Matches(a_pair.first) &&
-             second_matcher_.Matches(a_pair.second);
-    }
-    StringMatchResultListener first_inner_listener;
-    if (!first_matcher_.MatchAndExplain(a_pair.first,
-                                        &first_inner_listener)) {
-      *listener << "whose first field does not match";
-      PrintIfNotEmpty(first_inner_listener.str(), listener->stream());
-      return false;
-    }
-    StringMatchResultListener second_inner_listener;
-    if (!second_matcher_.MatchAndExplain(a_pair.second,
-                                         &second_inner_listener)) {
-      *listener << "whose second field does not match";
-      PrintIfNotEmpty(second_inner_listener.str(), listener->stream());
-      return false;
-    }
-    ExplainSuccess(first_inner_listener.str(), second_inner_listener.str(),
-                   listener);
-    return true;
-  }
-
- private:
-  void ExplainSuccess(const internal::string& first_explanation,
-                      const internal::string& second_explanation,
-                      MatchResultListener* listener) const {
-    *listener << "whose both fields match";
-    if (first_explanation != "") {
-      *listener << ", where the first field is a value " << first_explanation;
-    }
-    if (second_explanation != "") {
-      *listener << ", ";
-      if (first_explanation != "") {
-        *listener << "and ";
-      } else {
-        *listener << "where ";
-      }
-      *listener << "the second field is a value " << second_explanation;
-    }
-  }
-
-  const Matcher<const FirstType&> first_matcher_;
-  const Matcher<const SecondType&> second_matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(PairMatcherImpl);
-};
-
-// Implements polymorphic Pair(first_matcher, second_matcher).
-template <typename FirstMatcher, typename SecondMatcher>
-class PairMatcher {
- public:
-  PairMatcher(FirstMatcher first_matcher, SecondMatcher second_matcher)
-      : first_matcher_(first_matcher), second_matcher_(second_matcher) {}
-
-  template <typename PairType>
-  operator Matcher<PairType> () const {
-    return MakeMatcher(
-        new PairMatcherImpl<PairType>(
-            first_matcher_, second_matcher_));
-  }
-
- private:
-  const FirstMatcher first_matcher_;
-  const SecondMatcher second_matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(PairMatcher);
-};
-
-// Implements ElementsAre() and ElementsAreArray().
-template <typename Container>
-class ElementsAreMatcherImpl : public MatcherInterface<Container> {
- public:
-  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
-  typedef internal::StlContainerView<RawContainer> View;
-  typedef typename View::type StlContainer;
-  typedef typename View::const_reference StlContainerReference;
-  typedef typename StlContainer::value_type Element;
-
-  // Constructs the matcher from a sequence of element values or
-  // element matchers.
-  template <typename InputIter>
-  ElementsAreMatcherImpl(InputIter first, InputIter last) {
-    while (first != last) {
-      matchers_.push_back(MatcherCast<const Element&>(*first++));
-    }
-  }
-
-  // Describes what this matcher does.
-  virtual void DescribeTo(::std::ostream* os) const {
-    if (count() == 0) {
-      *os << "is empty";
-    } else if (count() == 1) {
-      *os << "has 1 element that ";
-      matchers_[0].DescribeTo(os);
-    } else {
-      *os << "has " << Elements(count()) << " where\n";
-      for (size_t i = 0; i != count(); ++i) {
-        *os << "element #" << i << " ";
-        matchers_[i].DescribeTo(os);
-        if (i + 1 < count()) {
-          *os << ",\n";
-        }
-      }
-    }
-  }
-
-  // Describes what the negation of this matcher does.
-  virtual void DescribeNegationTo(::std::ostream* os) const {
-    if (count() == 0) {
-      *os << "isn't empty";
-      return;
-    }
-
-    *os << "doesn't have " << Elements(count()) << ", or\n";
-    for (size_t i = 0; i != count(); ++i) {
-      *os << "element #" << i << " ";
-      matchers_[i].DescribeNegationTo(os);
-      if (i + 1 < count()) {
-        *os << ", or\n";
-      }
-    }
-  }
-
-  virtual bool MatchAndExplain(Container container,
-                               MatchResultListener* listener) const {
-    // To work with stream-like "containers", we must only walk
-    // through the elements in one pass.
-
-    const bool listener_interested = listener->IsInterested();
-
-    // explanations[i] is the explanation of the element at index i.
-    ::std::vector<internal::string> explanations(count());
-    StlContainerReference stl_container = View::ConstReference(container);
-    typename StlContainer::const_iterator it = stl_container.begin();
-    size_t exam_pos = 0;
-    bool mismatch_found = false;  // Have we found a mismatched element yet?
-
-    // Go through the elements and matchers in pairs, until we reach
-    // the end of either the elements or the matchers, or until we find a
-    // mismatch.
-    for (; it != stl_container.end() && exam_pos != count(); ++it, ++exam_pos) {
-      bool match;  // Does the current element match the current matcher?
-      if (listener_interested) {
-        StringMatchResultListener s;
-        match = matchers_[exam_pos].MatchAndExplain(*it, &s);
-        explanations[exam_pos] = s.str();
-      } else {
-        match = matchers_[exam_pos].Matches(*it);
-      }
-
-      if (!match) {
-        mismatch_found = true;
-        break;
-      }
-    }
-    // If mismatch_found is true, 'exam_pos' is the index of the mismatch.
-
-    // Find how many elements the actual container has.  We avoid
-    // calling size() s.t. this code works for stream-like "containers"
-    // that don't define size().
-    size_t actual_count = exam_pos;
-    for (; it != stl_container.end(); ++it) {
-      ++actual_count;
-    }
-
-    if (actual_count != count()) {
-      // The element count doesn't match.  If the container is empty,
-      // there's no need to explain anything as Google Mock already
-      // prints the empty container.  Otherwise we just need to show
-      // how many elements there actually are.
-      if (listener_interested && (actual_count != 0)) {
-        *listener << "which has " << Elements(actual_count);
-      }
-      return false;
-    }
-
-    if (mismatch_found) {
-      // The element count matches, but the exam_pos-th element doesn't match.
-      if (listener_interested) {
-        *listener << "whose element #" << exam_pos << " doesn't match";
-        PrintIfNotEmpty(explanations[exam_pos], listener->stream());
-      }
-      return false;
-    }
-
-    // Every element matches its expectation.  We need to explain why
-    // (the obvious ones can be skipped).
-    if (listener_interested) {
-      bool reason_printed = false;
-      for (size_t i = 0; i != count(); ++i) {
-        const internal::string& s = explanations[i];
-        if (!s.empty()) {
-          if (reason_printed) {
-            *listener << ",\nand ";
-          }
-          *listener << "whose element #" << i << " matches, " << s;
-          reason_printed = true;
-        }
-      }
-    }
-    return true;
-  }
-
- private:
-  static Message Elements(size_t count) {
-    return Message() << count << (count == 1 ? " element" : " elements");
-  }
-
-  size_t count() const { return matchers_.size(); }
-
-  ::std::vector<Matcher<const Element&> > matchers_;
-
-  GTEST_DISALLOW_ASSIGN_(ElementsAreMatcherImpl);
-};
-
-// Connectivity matrix of (elements X matchers), in element-major order.
-// Initially, there are no edges.
-// Use NextGraph() to iterate over all possible edge configurations.
-// Use Randomize() to generate a random edge configuration.
-class GTEST_API_ MatchMatrix {
- public:
-  MatchMatrix(size_t num_elements, size_t num_matchers)
-      : num_elements_(num_elements),
-        num_matchers_(num_matchers),
-        matched_(num_elements_* num_matchers_, 0) {
-  }
-
-  size_t LhsSize() const { return num_elements_; }
-  size_t RhsSize() const { return num_matchers_; }
-  bool HasEdge(size_t ilhs, size_t irhs) const {
-    return matched_[SpaceIndex(ilhs, irhs)] == 1;
-  }
-  void SetEdge(size_t ilhs, size_t irhs, bool b) {
-    matched_[SpaceIndex(ilhs, irhs)] = b ? 1 : 0;
-  }
-
-  // Treating the connectivity matrix as a (LhsSize()*RhsSize())-bit number,
-  // adds 1 to that number; returns false if incrementing the graph left it
-  // empty.
-  bool NextGraph();
-
-  void Randomize();
-
-  string DebugString() const;
-
- private:
-  size_t SpaceIndex(size_t ilhs, size_t irhs) const {
-    return ilhs * num_matchers_ + irhs;
-  }
-
-  size_t num_elements_;
-  size_t num_matchers_;
-
-  // Each element is a char interpreted as bool. They are stored as a
-  // flattened array in lhs-major order, use 'SpaceIndex()' to translate
-  // a (ilhs, irhs) matrix coordinate into an offset.
-  ::std::vector<char> matched_;
-};
-
-typedef ::std::pair<size_t, size_t> ElementMatcherPair;
-typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs;
-
-// Returns a maximum bipartite matching for the specified graph 'g'.
-// The matching is represented as a vector of {element, matcher} pairs.
-GTEST_API_ ElementMatcherPairs
-FindMaxBipartiteMatching(const MatchMatrix& g);
-
-GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
-                            MatchResultListener* listener);
-
-// Untyped base class for implementing UnorderedElementsAre.  By
-// putting logic that's not specific to the element type here, we
-// reduce binary bloat and increase compilation speed.
-class GTEST_API_ UnorderedElementsAreMatcherImplBase {
- protected:
-  // A vector of matcher describers, one for each element matcher.
-  // Does not own the describers (and thus can be used only when the
-  // element matchers are alive).
-  typedef ::std::vector<const MatcherDescriberInterface*> MatcherDescriberVec;
-
-  // Describes this UnorderedElementsAre matcher.
-  void DescribeToImpl(::std::ostream* os) const;
-
-  // Describes the negation of this UnorderedElementsAre matcher.
-  void DescribeNegationToImpl(::std::ostream* os) const;
-
-  bool VerifyAllElementsAndMatchersAreMatched(
-      const ::std::vector<string>& element_printouts,
-      const MatchMatrix& matrix,
-      MatchResultListener* listener) const;
-
-  MatcherDescriberVec& matcher_describers() {
-    return matcher_describers_;
-  }
-
-  static Message Elements(size_t n) {
-    return Message() << n << " element" << (n == 1 ? "" : "s");
-  }
-
- private:
-  MatcherDescriberVec matcher_describers_;
-
-  GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase);
-};
-
-// Implements unordered ElementsAre and unordered ElementsAreArray.
-template <typename Container>
-class UnorderedElementsAreMatcherImpl
-    : public MatcherInterface<Container>,
-      public UnorderedElementsAreMatcherImplBase {
- public:
-  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
-  typedef internal::StlContainerView<RawContainer> View;
-  typedef typename View::type StlContainer;
-  typedef typename View::const_reference StlContainerReference;
-  typedef typename StlContainer::const_iterator StlContainerConstIterator;
-  typedef typename StlContainer::value_type Element;
-
-  // Constructs the matcher from a sequence of element values or
-  // element matchers.
-  template <typename InputIter>
-  UnorderedElementsAreMatcherImpl(InputIter first, InputIter last) {
-    for (; first != last; ++first) {
-      matchers_.push_back(MatcherCast<const Element&>(*first));
-      matcher_describers().push_back(matchers_.back().GetDescriber());
-    }
-  }
-
-  // Describes what this matcher does.
-  virtual void DescribeTo(::std::ostream* os) const {
-    return UnorderedElementsAreMatcherImplBase::DescribeToImpl(os);
-  }
-
-  // Describes what the negation of this matcher does.
-  virtual void DescribeNegationTo(::std::ostream* os) const {
-    return UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(os);
-  }
-
-  virtual bool MatchAndExplain(Container container,
-                               MatchResultListener* listener) const {
-    StlContainerReference stl_container = View::ConstReference(container);
-    ::std::vector<string> element_printouts;
-    MatchMatrix matrix = AnalyzeElements(stl_container.begin(),
-                                         stl_container.end(),
-                                         &element_printouts,
-                                         listener);
-
-    const size_t actual_count = matrix.LhsSize();
-    if (actual_count == 0 && matchers_.empty()) {
-      return true;
-    }
-    if (actual_count != matchers_.size()) {
-      // The element count doesn't match.  If the container is empty,
-      // there's no need to explain anything as Google Mock already
-      // prints the empty container. Otherwise we just need to show
-      // how many elements there actually are.
-      if (actual_count != 0 && listener->IsInterested()) {
-        *listener << "which has " << Elements(actual_count);
-      }
-      return false;
-    }
-
-    return VerifyAllElementsAndMatchersAreMatched(element_printouts,
-                                                  matrix, listener) &&
-           FindPairing(matrix, listener);
-  }
-
- private:
-  typedef ::std::vector<Matcher<const Element&> > MatcherVec;
-
-  template <typename ElementIter>
-  MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
-                              ::std::vector<string>* element_printouts,
-                              MatchResultListener* listener) const {
-    element_printouts->clear();
-    ::std::vector<char> did_match;
-    size_t num_elements = 0;
-    for (; elem_first != elem_last; ++num_elements, ++elem_first) {
-      if (listener->IsInterested()) {
-        element_printouts->push_back(PrintToString(*elem_first));
-      }
-      for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) {
-        did_match.push_back(Matches(matchers_[irhs])(*elem_first));
-      }
-    }
-
-    MatchMatrix matrix(num_elements, matchers_.size());
-    ::std::vector<char>::const_iterator did_match_iter = did_match.begin();
-    for (size_t ilhs = 0; ilhs != num_elements; ++ilhs) {
-      for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) {
-        matrix.SetEdge(ilhs, irhs, *did_match_iter++ != 0);
-      }
-    }
-    return matrix;
-  }
-
-  MatcherVec matchers_;
-
-  GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl);
-};
-
-// Functor for use in TransformTuple.
-// Performs MatcherCast<Target> on an input argument of any type.
-template <typename Target>
-struct CastAndAppendTransform {
-  template <typename Arg>
-  Matcher<Target> operator()(const Arg& a) const {
-    return MatcherCast<Target>(a);
-  }
-};
-
-// Implements UnorderedElementsAre.
-template <typename MatcherTuple>
-class UnorderedElementsAreMatcher {
- public:
-  explicit UnorderedElementsAreMatcher(const MatcherTuple& args)
-      : matchers_(args) {}
-
-  template <typename Container>
-  operator Matcher<Container>() const {
-    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
-    typedef typename internal::StlContainerView<RawContainer>::type View;
-    typedef typename View::value_type Element;
-    typedef ::std::vector<Matcher<const Element&> > MatcherVec;
-    MatcherVec matchers;
-    matchers.reserve(::testing::tuple_size<MatcherTuple>::value);
-    TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
-                         ::std::back_inserter(matchers));
-    return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
-                           matchers.begin(), matchers.end()));
-  }
-
- private:
-  const MatcherTuple matchers_;
-  GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcher);
-};
-
-// Implements ElementsAre.
-template <typename MatcherTuple>
-class ElementsAreMatcher {
- public:
-  explicit ElementsAreMatcher(const MatcherTuple& args) : matchers_(args) {}
-
-  template <typename Container>
-  operator Matcher<Container>() const {
-    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
-    typedef typename internal::StlContainerView<RawContainer>::type View;
-    typedef typename View::value_type Element;
-    typedef ::std::vector<Matcher<const Element&> > MatcherVec;
-    MatcherVec matchers;
-    matchers.reserve(::testing::tuple_size<MatcherTuple>::value);
-    TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
-                         ::std::back_inserter(matchers));
-    return MakeMatcher(new ElementsAreMatcherImpl<Container>(
-                           matchers.begin(), matchers.end()));
-  }
-
- private:
-  const MatcherTuple matchers_;
-  GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher);
-};
-
-// Implements UnorderedElementsAreArray().
-template <typename T>
-class UnorderedElementsAreArrayMatcher {
- public:
-  UnorderedElementsAreArrayMatcher() {}
-
-  template <typename Iter>
-  UnorderedElementsAreArrayMatcher(Iter first, Iter last)
-      : matchers_(first, last) {}
-
-  template <typename Container>
-  operator Matcher<Container>() const {
-    return MakeMatcher(
-        new UnorderedElementsAreMatcherImpl<Container>(matchers_.begin(),
-                                                       matchers_.end()));
-  }
-
- private:
-  ::std::vector<T> matchers_;
-
-  GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher);
-};
-
-// Implements ElementsAreArray().
-template <typename T>
-class ElementsAreArrayMatcher {
- public:
-  template <typename Iter>
-  ElementsAreArrayMatcher(Iter first, Iter last) : matchers_(first, last) {}
-
-  template <typename Container>
-  operator Matcher<Container>() const {
-    return MakeMatcher(new ElementsAreMatcherImpl<Container>(
-        matchers_.begin(), matchers_.end()));
-  }
-
- private:
-  const ::std::vector<T> matchers_;
-
-  GTEST_DISALLOW_ASSIGN_(ElementsAreArrayMatcher);
-};
-
-// Given a 2-tuple matcher tm of type Tuple2Matcher and a value second
-// of type Second, BoundSecondMatcher<Tuple2Matcher, Second>(tm,
-// second) is a polymorphic matcher that matches a value x iff tm
-// matches tuple (x, second).  Useful for implementing
-// UnorderedPointwise() in terms of UnorderedElementsAreArray().
-//
-// BoundSecondMatcher is copyable and assignable, as we need to put
-// instances of this class in a vector when implementing
-// UnorderedPointwise().
-template <typename Tuple2Matcher, typename Second>
-class BoundSecondMatcher {
- public:
-  BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second)
-      : tuple2_matcher_(tm), second_value_(second) {}
-
-  template <typename T>
-  operator Matcher<T>() const {
-    return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_));
-  }
-
-  // We have to define this for UnorderedPointwise() to compile in
-  // C++98 mode, as it puts BoundSecondMatcher instances in a vector,
-  // which requires the elements to be assignable in C++98.  The
-  // compiler cannot generate the operator= for us, as Tuple2Matcher
-  // and Second may not be assignable.
-  //
-  // However, this should never be called, so the implementation just
-  // need to assert.
-  void operator=(const BoundSecondMatcher& /*rhs*/) {
-    GTEST_LOG_(FATAL) << "BoundSecondMatcher should never be assigned.";
-  }
-
- private:
-  template <typename T>
-  class Impl : public MatcherInterface<T> {
-   public:
-    typedef ::testing::tuple<T, Second> ArgTuple;
-
-    Impl(const Tuple2Matcher& tm, const Second& second)
-        : mono_tuple2_matcher_(SafeMatcherCast<const ArgTuple&>(tm)),
-          second_value_(second) {}
-
-    virtual void DescribeTo(::std::ostream* os) const {
-      *os << "and ";
-      UniversalPrint(second_value_, os);
-      *os << " ";
-      mono_tuple2_matcher_.DescribeTo(os);
-    }
-
-    virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
-      return mono_tuple2_matcher_.MatchAndExplain(ArgTuple(x, second_value_),
-                                                  listener);
-    }
-
-   private:
-    const Matcher<const ArgTuple&> mono_tuple2_matcher_;
-    const Second second_value_;
-
-    GTEST_DISALLOW_ASSIGN_(Impl);
-  };
-
-  const Tuple2Matcher tuple2_matcher_;
-  const Second second_value_;
-};
-
-// Given a 2-tuple matcher tm and a value second,
-// MatcherBindSecond(tm, second) returns a matcher that matches a
-// value x iff tm matches tuple (x, second).  Useful for implementing
-// UnorderedPointwise() in terms of UnorderedElementsAreArray().
-template <typename Tuple2Matcher, typename Second>
-BoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond(
-    const Tuple2Matcher& tm, const Second& second) {
-  return BoundSecondMatcher<Tuple2Matcher, Second>(tm, second);
-}
-
-// Returns the description for a matcher defined using the MATCHER*()
-// macro where the user-supplied description string is "", if
-// 'negation' is false; otherwise returns the description of the
-// negation of the matcher.  'param_values' contains a list of strings
-// that are the print-out of the matcher's parameters.
-GTEST_API_ string FormatMatcherDescription(bool negation,
-                                           const char* matcher_name,
-                                           const Strings& param_values);
-
-}  // namespace internal
-
-// ElementsAreArray(first, last)
-// ElementsAreArray(pointer, count)
-// ElementsAreArray(array)
-// ElementsAreArray(container)
-// ElementsAreArray({ e1, e2, ..., en })
-//
-// The ElementsAreArray() functions are like ElementsAre(...), except
-// that they are given a homogeneous sequence rather than taking each
-// element as a function argument. The sequence can be specified as an
-// array, a pointer and count, a vector, an initializer list, or an
-// STL iterator range. In each of these cases, the underlying sequence
-// can be either a sequence of values or a sequence of matchers.
-//
-// All forms of ElementsAreArray() make a copy of the input matcher sequence.
-
-template <typename Iter>
-inline internal::ElementsAreArrayMatcher<
-    typename ::std::iterator_traits<Iter>::value_type>
-ElementsAreArray(Iter first, Iter last) {
-  typedef typename ::std::iterator_traits<Iter>::value_type T;
-  return internal::ElementsAreArrayMatcher<T>(first, last);
-}
-
-template <typename T>
-inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
-    const T* pointer, size_t count) {
-  return ElementsAreArray(pointer, pointer + count);
-}
-
-template <typename T, size_t N>
-inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(
-    const T (&array)[N]) {
-  return ElementsAreArray(array, N);
-}
-
-template <typename Container>
-inline internal::ElementsAreArrayMatcher<typename Container::value_type>
-ElementsAreArray(const Container& container) {
-  return ElementsAreArray(container.begin(), container.end());
-}
-
-#if GTEST_HAS_STD_INITIALIZER_LIST_
-template <typename T>
-inline internal::ElementsAreArrayMatcher<T>
-ElementsAreArray(::std::initializer_list<T> xs) {
-  return ElementsAreArray(xs.begin(), xs.end());
-}
-#endif
-
-// UnorderedElementsAreArray(first, last)
-// UnorderedElementsAreArray(pointer, count)
-// UnorderedElementsAreArray(array)
-// UnorderedElementsAreArray(container)
-// UnorderedElementsAreArray({ e1, e2, ..., en })
-//
-// The UnorderedElementsAreArray() functions are like
-// ElementsAreArray(...), but allow matching the elements in any order.
-template <typename Iter>
-inline internal::UnorderedElementsAreArrayMatcher<
-    typename ::std::iterator_traits<Iter>::value_type>
-UnorderedElementsAreArray(Iter first, Iter last) {
-  typedef typename ::std::iterator_traits<Iter>::value_type T;
-  return internal::UnorderedElementsAreArrayMatcher<T>(first, last);
-}
-
-template <typename T>
-inline internal::UnorderedElementsAreArrayMatcher<T>
-UnorderedElementsAreArray(const T* pointer, size_t count) {
-  return UnorderedElementsAreArray(pointer, pointer + count);
-}
-
-template <typename T, size_t N>
-inline internal::UnorderedElementsAreArrayMatcher<T>
-UnorderedElementsAreArray(const T (&array)[N]) {
-  return UnorderedElementsAreArray(array, N);
-}
-
-template <typename Container>
-inline internal::UnorderedElementsAreArrayMatcher<
-    typename Container::value_type>
-UnorderedElementsAreArray(const Container& container) {
-  return UnorderedElementsAreArray(container.begin(), container.end());
-}
-
-#if GTEST_HAS_STD_INITIALIZER_LIST_
-template <typename T>
-inline internal::UnorderedElementsAreArrayMatcher<T>
-UnorderedElementsAreArray(::std::initializer_list<T> xs) {
-  return UnorderedElementsAreArray(xs.begin(), xs.end());
-}
-#endif
-
-// _ is a matcher that matches anything of any type.
-//
-// This definition is fine as:
-//
-//   1. The C++ standard permits using the name _ in a namespace that
-//      is not the global namespace or ::std.
-//   2. The AnythingMatcher class has no data member or constructor,
-//      so it's OK to create global variables of this type.
-//   3. c-style has approved of using _ in this case.
-const internal::AnythingMatcher _ = {};
-// Creates a matcher that matches any value of the given type T.
-template <typename T>
-inline Matcher<T> A() { return MakeMatcher(new internal::AnyMatcherImpl<T>()); }
-
-// Creates a matcher that matches any value of the given type T.
-template <typename T>
-inline Matcher<T> An() { return A<T>(); }
-
-// Creates a polymorphic matcher that matches anything equal to x.
-// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
-// wouldn't compile.
-template <typename T>
-inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }
-
-// Constructs a Matcher<T> from a 'value' of type T.  The constructed
-// matcher matches any value that's equal to 'value'.
-template <typename T>
-Matcher<T>::Matcher(T value) { *this = Eq(value); }
-
-// Creates a monomorphic matcher that matches anything with type Lhs
-// and equal to rhs.  A user may need to use this instead of Eq(...)
-// in order to resolve an overloading ambiguity.
-//
-// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))
-// or Matcher<T>(x), but more readable than the latter.
-//
-// We could define similar monomorphic matchers for other comparison
-// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do
-// it yet as those are used much less than Eq() in practice.  A user
-// can always write Matcher<T>(Lt(5)) to be explicit about the type,
-// for example.
-template <typename Lhs, typename Rhs>
-inline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); }
-
-// Creates a polymorphic matcher that matches anything >= x.
-template <typename Rhs>
-inline internal::GeMatcher<Rhs> Ge(Rhs x) {
-  return internal::GeMatcher<Rhs>(x);
-}
-
-// Creates a polymorphic matcher that matches anything > x.
-template <typename Rhs>
-inline internal::GtMatcher<Rhs> Gt(Rhs x) {
-  return internal::GtMatcher<Rhs>(x);
-}
-
-// Creates a polymorphic matcher that matches anything <= x.
-template <typename Rhs>
-inline internal::LeMatcher<Rhs> Le(Rhs x) {
-  return internal::LeMatcher<Rhs>(x);
-}
-
-// Creates a polymorphic matcher that matches anything < x.
-template <typename Rhs>
-inline internal::LtMatcher<Rhs> Lt(Rhs x) {
-  return internal::LtMatcher<Rhs>(x);
-}
-
-// Creates a polymorphic matcher that matches anything != x.
-template <typename Rhs>
-inline internal::NeMatcher<Rhs> Ne(Rhs x) {
-  return internal::NeMatcher<Rhs>(x);
-}
-
-// Creates a polymorphic matcher that matches any NULL pointer.
-inline PolymorphicMatcher<internal::IsNullMatcher > IsNull() {
-  return MakePolymorphicMatcher(internal::IsNullMatcher());
-}
-
-// Creates a polymorphic matcher that matches any non-NULL pointer.
-// This is convenient as Not(NULL) doesn't compile (the compiler
-// thinks that that expression is comparing a pointer with an integer).
-inline PolymorphicMatcher<internal::NotNullMatcher > NotNull() {
-  return MakePolymorphicMatcher(internal::NotNullMatcher());
-}
-
-// Creates a polymorphic matcher that matches any argument that
-// references variable x.
-template <typename T>
-inline internal::RefMatcher<T&> Ref(T& x) {  // NOLINT
-  return internal::RefMatcher<T&>(x);
-}
-
-// Creates a matcher that matches any double argument approximately
-// equal to rhs, where two NANs are considered unequal.
-inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) {
-  return internal::FloatingEqMatcher<double>(rhs, false);
-}
-
-// Creates a matcher that matches any double argument approximately
-// equal to rhs, including NaN values when rhs is NaN.
-inline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) {
-  return internal::FloatingEqMatcher<double>(rhs, true);
-}
-
-// Creates a matcher that matches any double argument approximately equal to
-// rhs, up to the specified max absolute error bound, where two NANs are
-// considered unequal.  The max absolute error bound must be non-negative.
-inline internal::FloatingEqMatcher<double> DoubleNear(
-    double rhs, double max_abs_error) {
-  return internal::FloatingEqMatcher<double>(rhs, false, max_abs_error);
-}
-
-// Creates a matcher that matches any double argument approximately equal to
-// rhs, up to the specified max absolute error bound, including NaN values when
-// rhs is NaN.  The max absolute error bound must be non-negative.
-inline internal::FloatingEqMatcher<double> NanSensitiveDoubleNear(
-    double rhs, double max_abs_error) {
-  return internal::FloatingEqMatcher<double>(rhs, true, max_abs_error);
-}
-
-// Creates a matcher that matches any float argument approximately
-// equal to rhs, where two NANs are considered unequal.
-inline internal::FloatingEqMatcher<float> FloatEq(float rhs) {
-  return internal::FloatingEqMatcher<float>(rhs, false);
-}
-
-// Creates a matcher that matches any float argument approximately
-// equal to rhs, including NaN values when rhs is NaN.
-inline internal::FloatingEqMatcher<float> NanSensitiveFloatEq(float rhs) {
-  return internal::FloatingEqMatcher<float>(rhs, true);
-}
-
-// Creates a matcher that matches any float argument approximately equal to
-// rhs, up to the specified max absolute error bound, where two NANs are
-// considered unequal.  The max absolute error bound must be non-negative.
-inline internal::FloatingEqMatcher<float> FloatNear(
-    float rhs, float max_abs_error) {
-  return internal::FloatingEqMatcher<float>(rhs, false, max_abs_error);
-}
-
-// Creates a matcher that matches any float argument approximately equal to
-// rhs, up to the specified max absolute error bound, including NaN values when
-// rhs is NaN.  The max absolute error bound must be non-negative.
-inline internal::FloatingEqMatcher<float> NanSensitiveFloatNear(
-    float rhs, float max_abs_error) {
-  return internal::FloatingEqMatcher<float>(rhs, true, max_abs_error);
-}
-
-// Creates a matcher that matches a pointer (raw or smart) that points
-// to a value that matches inner_matcher.
-template <typename InnerMatcher>
-inline internal::PointeeMatcher<InnerMatcher> Pointee(
-    const InnerMatcher& inner_matcher) {
-  return internal::PointeeMatcher<InnerMatcher>(inner_matcher);
-}
-
-// Creates a matcher that matches a pointer or reference that matches
-// inner_matcher when dynamic_cast<To> is applied.
-// The result of dynamic_cast<To> is forwarded to the inner matcher.
-// If To is a pointer and the cast fails, the inner matcher will receive NULL.
-// If To is a reference and the cast fails, this matcher returns false
-// immediately.
-template <typename To>
-inline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To> >
-WhenDynamicCastTo(const Matcher<To>& inner_matcher) {
-  return MakePolymorphicMatcher(
-      internal::WhenDynamicCastToMatcher<To>(inner_matcher));
-}
-
-// Creates a matcher that matches an object whose given field matches
-// 'matcher'.  For example,
-//   Field(&Foo::number, Ge(5))
-// matches a Foo object x iff x.number >= 5.
-template <typename Class, typename FieldType, typename FieldMatcher>
-inline PolymorphicMatcher<
-  internal::FieldMatcher<Class, FieldType> > Field(
-    FieldType Class::*field, const FieldMatcher& matcher) {
-  return MakePolymorphicMatcher(
-      internal::FieldMatcher<Class, FieldType>(
-          field, MatcherCast<const FieldType&>(matcher)));
-  // The call to MatcherCast() is required for supporting inner
-  // matchers of compatible types.  For example, it allows
-  //   Field(&Foo::bar, m)
-  // to compile where bar is an int32 and m is a matcher for int64.
-}
-
-// Creates a matcher that matches an object whose given property
-// matches 'matcher'.  For example,
-//   Property(&Foo::str, StartsWith("hi"))
-// matches a Foo object x iff x.str() starts with "hi".
-template <typename Class, typename PropertyType, typename PropertyMatcher>
-inline PolymorphicMatcher<
-  internal::PropertyMatcher<Class, PropertyType> > Property(
-    PropertyType (Class::*property)() const, const PropertyMatcher& matcher) {
-  return MakePolymorphicMatcher(
-      internal::PropertyMatcher<Class, PropertyType>(
-          property,
-          MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher)));
-  // The call to MatcherCast() is required for supporting inner
-  // matchers of compatible types.  For example, it allows
-  //   Property(&Foo::bar, m)
-  // to compile where bar() returns an int32 and m is a matcher for int64.
-}
-
-// Creates a matcher that matches an object iff the result of applying
-// a callable to x matches 'matcher'.
-// For example,
-//   ResultOf(f, StartsWith("hi"))
-// matches a Foo object x iff f(x) starts with "hi".
-// callable parameter can be a function, function pointer, or a functor.
-// Callable has to satisfy the following conditions:
-//   * It is required to keep no state affecting the results of
-//     the calls on it and make no assumptions about how many calls
-//     will be made. Any state it keeps must be protected from the
-//     concurrent access.
-//   * If it is a function object, it has to define type result_type.
-//     We recommend deriving your functor classes from std::unary_function.
-template <typename Callable, typename ResultOfMatcher>
-internal::ResultOfMatcher<Callable> ResultOf(
-    Callable callable, const ResultOfMatcher& matcher) {
-  return internal::ResultOfMatcher<Callable>(
-          callable,
-          MatcherCast<typename internal::CallableTraits<Callable>::ResultType>(
-              matcher));
-  // The call to MatcherCast() is required for supporting inner
-  // matchers of compatible types.  For example, it allows
-  //   ResultOf(Function, m)
-  // to compile where Function() returns an int32 and m is a matcher for int64.
-}
-
-// String matchers.
-
-// Matches a string equal to str.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> >
-    StrEq(const internal::string& str) {
-  return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>(
-      str, true, true));
-}
-
-// Matches a string not equal to str.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> >
-    StrNe(const internal::string& str) {
-  return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>(
-      str, false, true));
-}
-
-// Matches a string equal to str, ignoring case.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> >
-    StrCaseEq(const internal::string& str) {
-  return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>(
-      str, true, false));
-}
-
-// Matches a string not equal to str, ignoring case.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> >
-    StrCaseNe(const internal::string& str) {
-  return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>(
-      str, false, false));
-}
-
-// Creates a matcher that matches any string, std::string, or C string
-// that contains the given substring.
-inline PolymorphicMatcher<internal::HasSubstrMatcher<internal::string> >
-    HasSubstr(const internal::string& substring) {
-  return MakePolymorphicMatcher(internal::HasSubstrMatcher<internal::string>(
-      substring));
-}
-
-// Matches a string that starts with 'prefix' (case-sensitive).
-inline PolymorphicMatcher<internal::StartsWithMatcher<internal::string> >
-    StartsWith(const internal::string& prefix) {
-  return MakePolymorphicMatcher(internal::StartsWithMatcher<internal::string>(
-      prefix));
-}
-
-// Matches a string that ends with 'suffix' (case-sensitive).
-inline PolymorphicMatcher<internal::EndsWithMatcher<internal::string> >
-    EndsWith(const internal::string& suffix) {
-  return MakePolymorphicMatcher(internal::EndsWithMatcher<internal::string>(
-      suffix));
-}
-
-// Matches a string that fully matches regular expression 'regex'.
-// The matcher takes ownership of 'regex'.
-inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
-    const internal::RE* regex) {
-  return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
-}
-inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
-    const internal::string& regex) {
-  return MatchesRegex(new internal::RE(regex));
-}
-
-// Matches a string that contains regular expression 'regex'.
-// The matcher takes ownership of 'regex'.
-inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
-    const internal::RE* regex) {
-  return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
-}
-inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
-    const internal::string& regex) {
-  return ContainsRegex(new internal::RE(regex));
-}
-
-#if GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING
-// Wide string matchers.
-
-// Matches a string equal to str.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> >
-    StrEq(const internal::wstring& str) {
-  return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>(
-      str, true, true));
-}
-
-// Matches a string not equal to str.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> >
-    StrNe(const internal::wstring& str) {
-  return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>(
-      str, false, true));
-}
-
-// Matches a string equal to str, ignoring case.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> >
-    StrCaseEq(const internal::wstring& str) {
-  return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>(
-      str, true, false));
-}
-
-// Matches a string not equal to str, ignoring case.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> >
-    StrCaseNe(const internal::wstring& str) {
-  return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>(
-      str, false, false));
-}
-
-// Creates a matcher that matches any wstring, std::wstring, or C wide string
-// that contains the given substring.
-inline PolymorphicMatcher<internal::HasSubstrMatcher<internal::wstring> >
-    HasSubstr(const internal::wstring& substring) {
-  return MakePolymorphicMatcher(internal::HasSubstrMatcher<internal::wstring>(
-      substring));
-}
-
-// Matches a string that starts with 'prefix' (case-sensitive).
-inline PolymorphicMatcher<internal::StartsWithMatcher<internal::wstring> >
-    StartsWith(const internal::wstring& prefix) {
-  return MakePolymorphicMatcher(internal::StartsWithMatcher<internal::wstring>(
-      prefix));
-}
-
-// Matches a string that ends with 'suffix' (case-sensitive).
-inline PolymorphicMatcher<internal::EndsWithMatcher<internal::wstring> >
-    EndsWith(const internal::wstring& suffix) {
-  return MakePolymorphicMatcher(internal::EndsWithMatcher<internal::wstring>(
-      suffix));
-}
-
-#endif  // GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING
-
-// Creates a polymorphic matcher that matches a 2-tuple where the
-// first field == the second field.
-inline internal::Eq2Matcher Eq() { return internal::Eq2Matcher(); }
-
-// Creates a polymorphic matcher that matches a 2-tuple where the
-// first field >= the second field.
-inline internal::Ge2Matcher Ge() { return internal::Ge2Matcher(); }
-
-// Creates a polymorphic matcher that matches a 2-tuple where the
-// first field > the second field.
-inline internal::Gt2Matcher Gt() { return internal::Gt2Matcher(); }
-
-// Creates a polymorphic matcher that matches a 2-tuple where the
-// first field <= the second field.
-inline internal::Le2Matcher Le() { return internal::Le2Matcher(); }
-
-// Creates a polymorphic matcher that matches a 2-tuple where the
-// first field < the second field.
-inline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); }
-
-// Creates a polymorphic matcher that matches a 2-tuple where the
-// first field != the second field.
-inline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); }
-
-// Creates a matcher that matches any value of type T that m doesn't
-// match.
-template <typename InnerMatcher>
-inline internal::NotMatcher<InnerMatcher> Not(InnerMatcher m) {
-  return internal::NotMatcher<InnerMatcher>(m);
-}
-
-// Returns a matcher that matches anything that satisfies the given
-// predicate.  The predicate can be any unary function or functor
-// whose return type can be implicitly converted to bool.
-template <typename Predicate>
-inline PolymorphicMatcher<internal::TrulyMatcher<Predicate> >
-Truly(Predicate pred) {
-  return MakePolymorphicMatcher(internal::TrulyMatcher<Predicate>(pred));
-}
-
-// Returns a matcher that matches the container size. The container must
-// support both size() and size_type which all STL-like containers provide.
-// Note that the parameter 'size' can be a value of type size_type as well as
-// matcher. For instance:
-//   EXPECT_THAT(container, SizeIs(2));     // Checks container has 2 elements.
-//   EXPECT_THAT(container, SizeIs(Le(2));  // Checks container has at most 2.
-template <typename SizeMatcher>
-inline internal::SizeIsMatcher<SizeMatcher>
-SizeIs(const SizeMatcher& size_matcher) {
-  return internal::SizeIsMatcher<SizeMatcher>(size_matcher);
-}
-
-// Returns a matcher that matches the distance between the container's begin()
-// iterator and its end() iterator, i.e. the size of the container. This matcher
-// can be used instead of SizeIs with containers such as std::forward_list which
-// do not implement size(). The container must provide const_iterator (with
-// valid iterator_traits), begin() and end().
-template <typename DistanceMatcher>
-inline internal::BeginEndDistanceIsMatcher<DistanceMatcher>
-BeginEndDistanceIs(const DistanceMatcher& distance_matcher) {
-  return internal::BeginEndDistanceIsMatcher<DistanceMatcher>(distance_matcher);
-}
-
-// Returns a matcher that matches an equal container.
-// This matcher behaves like Eq(), but in the event of mismatch lists the
-// values that are included in one container but not the other. (Duplicate
-// values and order differences are not explained.)
-template <typename Container>
-inline PolymorphicMatcher<internal::ContainerEqMatcher<  // NOLINT
-                            GTEST_REMOVE_CONST_(Container)> >
-    ContainerEq(const Container& rhs) {
-  // This following line is for working around a bug in MSVC 8.0,
-  // which causes Container to be a const type sometimes.
-  typedef GTEST_REMOVE_CONST_(Container) RawContainer;
-  return MakePolymorphicMatcher(
-      internal::ContainerEqMatcher<RawContainer>(rhs));
-}
-
-// Returns a matcher that matches a container that, when sorted using
-// the given comparator, matches container_matcher.
-template <typename Comparator, typename ContainerMatcher>
-inline internal::WhenSortedByMatcher<Comparator, ContainerMatcher>
-WhenSortedBy(const Comparator& comparator,
-             const ContainerMatcher& container_matcher) {
-  return internal::WhenSortedByMatcher<Comparator, ContainerMatcher>(
-      comparator, container_matcher);
-}
-
-// Returns a matcher that matches a container that, when sorted using
-// the < operator, matches container_matcher.
-template <typename ContainerMatcher>
-inline internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher>
-WhenSorted(const ContainerMatcher& container_matcher) {
-  return
-      internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher>(
-          internal::LessComparator(), container_matcher);
-}
-
-// Matches an STL-style container or a native array that contains the
-// same number of elements as in rhs, where its i-th element and rhs's
-// i-th element (as a pair) satisfy the given pair matcher, for all i.
-// TupleMatcher must be able to be safely cast to Matcher<tuple<const
-// T1&, const T2&> >, where T1 and T2 are the types of elements in the
-// LHS container and the RHS container respectively.
-template <typename TupleMatcher, typename Container>
-inline internal::PointwiseMatcher<TupleMatcher,
-                                  GTEST_REMOVE_CONST_(Container)>
-Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) {
-  // This following line is for working around a bug in MSVC 8.0,
-  // which causes Container to be a const type sometimes (e.g. when
-  // rhs is a const int[])..
-  typedef GTEST_REMOVE_CONST_(Container) RawContainer;
-  return internal::PointwiseMatcher<TupleMatcher, RawContainer>(
-      tuple_matcher, rhs);
-}
-
-#if GTEST_HAS_STD_INITIALIZER_LIST_
-
-// Supports the Pointwise(m, {a, b, c}) syntax.
-template <typename TupleMatcher, typename T>
-inline internal::PointwiseMatcher<TupleMatcher, std::vector<T> > Pointwise(
-    const TupleMatcher& tuple_matcher, std::initializer_list<T> rhs) {
-  return Pointwise(tuple_matcher, std::vector<T>(rhs));
-}
-
-#endif  // GTEST_HAS_STD_INITIALIZER_LIST_
-
-// UnorderedPointwise(pair_matcher, rhs) matches an STL-style
-// container or a native array that contains the same number of
-// elements as in rhs, where in some permutation of the container, its
-// i-th element and rhs's i-th element (as a pair) satisfy the given
-// pair matcher, for all i.  Tuple2Matcher must be able to be safely
-// cast to Matcher<tuple<const T1&, const T2&> >, where T1 and T2 are
-// the types of elements in the LHS container and the RHS container
-// respectively.
-//
-// This is like Pointwise(pair_matcher, rhs), except that the element
-// order doesn't matter.
-template <typename Tuple2Matcher, typename RhsContainer>
-inline internal::UnorderedElementsAreArrayMatcher<
-    typename internal::BoundSecondMatcher<
-        Tuple2Matcher, typename internal::StlContainerView<GTEST_REMOVE_CONST_(
-                           RhsContainer)>::type::value_type> >
-UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
-                   const RhsContainer& rhs_container) {
-  // This following line is for working around a bug in MSVC 8.0,
-  // which causes RhsContainer to be a const type sometimes (e.g. when
-  // rhs_container is a const int[]).
-  typedef GTEST_REMOVE_CONST_(RhsContainer) RawRhsContainer;
-
-  // RhsView allows the same code to handle RhsContainer being a
-  // STL-style container and it being a native C-style array.
-  typedef typename internal::StlContainerView<RawRhsContainer> RhsView;
-  typedef typename RhsView::type RhsStlContainer;
-  typedef typename RhsStlContainer::value_type Second;
-  const RhsStlContainer& rhs_stl_container =
-      RhsView::ConstReference(rhs_container);
-
-  // Create a matcher for each element in rhs_container.
-  ::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second> > matchers;
-  for (typename RhsStlContainer::const_iterator it = rhs_stl_container.begin();
-       it != rhs_stl_container.end(); ++it) {
-    matchers.push_back(
-        internal::MatcherBindSecond(tuple2_matcher, *it));
-  }
-
-  // Delegate the work to UnorderedElementsAreArray().
-  return UnorderedElementsAreArray(matchers);
-}
-
-#if GTEST_HAS_STD_INITIALIZER_LIST_
-
-// Supports the UnorderedPointwise(m, {a, b, c}) syntax.
-template <typename Tuple2Matcher, typename T>
-inline internal::UnorderedElementsAreArrayMatcher<
-    typename internal::BoundSecondMatcher<Tuple2Matcher, T> >
-UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
-                   std::initializer_list<T> rhs) {
-  return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs));
-}
-
-#endif  // GTEST_HAS_STD_INITIALIZER_LIST_
-
-// Matches an STL-style container or a native array that contains at
-// least one element matching the given value or matcher.
-//
-// Examples:
-//   ::std::set<int> page_ids;
-//   page_ids.insert(3);
-//   page_ids.insert(1);
-//   EXPECT_THAT(page_ids, Contains(1));
-//   EXPECT_THAT(page_ids, Contains(Gt(2)));
-//   EXPECT_THAT(page_ids, Not(Contains(4)));
-//
-//   ::std::map<int, size_t> page_lengths;
-//   page_lengths[1] = 100;
-//   EXPECT_THAT(page_lengths,
-//               Contains(::std::pair<const int, size_t>(1, 100)));
-//
-//   const char* user_ids[] = { "joe", "mike", "tom" };
-//   EXPECT_THAT(user_ids, Contains(Eq(::std::string("tom"))));
-template <typename M>
-inline internal::ContainsMatcher<M> Contains(M matcher) {
-  return internal::ContainsMatcher<M>(matcher);
-}
-
-// Matches an STL-style container or a native array that contains only
-// elements matching the given value or matcher.
-//
-// Each(m) is semantically equivalent to Not(Contains(Not(m))). Only
-// the messages are different.
-//
-// Examples:
-//   ::std::set<int> page_ids;
-//   // Each(m) matches an empty container, regardless of what m is.
-//   EXPECT_THAT(page_ids, Each(Eq(1)));
-//   EXPECT_THAT(page_ids, Each(Eq(77)));
-//
-//   page_ids.insert(3);
-//   EXPECT_THAT(page_ids, Each(Gt(0)));
-//   EXPECT_THAT(page_ids, Not(Each(Gt(4))));
-//   page_ids.insert(1);
-//   EXPECT_THAT(page_ids, Not(Each(Lt(2))));
-//
-//   ::std::map<int, size_t> page_lengths;
-//   page_lengths[1] = 100;
-//   page_lengths[2] = 200;
-//   page_lengths[3] = 300;
-//   EXPECT_THAT(page_lengths, Not(Each(Pair(1, 100))));
-//   EXPECT_THAT(page_lengths, Each(Key(Le(3))));
-//
-//   const char* user_ids[] = { "joe", "mike", "tom" };
-//   EXPECT_THAT(user_ids, Not(Each(Eq(::std::string("tom")))));
-template <typename M>
-inline internal::EachMatcher<M> Each(M matcher) {
-  return internal::EachMatcher<M>(matcher);
-}
-
-// Key(inner_matcher) matches an std::pair whose 'first' field matches
-// inner_matcher.  For example, Contains(Key(Ge(5))) can be used to match an
-// std::map that contains at least one element whose key is >= 5.
-template <typename M>
-inline internal::KeyMatcher<M> Key(M inner_matcher) {
-  return internal::KeyMatcher<M>(inner_matcher);
-}
-
-// Pair(first_matcher, second_matcher) matches a std::pair whose 'first' field
-// matches first_matcher and whose 'second' field matches second_matcher.  For
-// example, EXPECT_THAT(map_type, ElementsAre(Pair(Ge(5), "foo"))) can be used
-// to match a std::map<int, string> that contains exactly one element whose key
-// is >= 5 and whose value equals "foo".
-template <typename FirstMatcher, typename SecondMatcher>
-inline internal::PairMatcher<FirstMatcher, SecondMatcher>
-Pair(FirstMatcher first_matcher, SecondMatcher second_matcher) {
-  return internal::PairMatcher<FirstMatcher, SecondMatcher>(
-      first_matcher, second_matcher);
-}
-
-// Returns a predicate that is satisfied by anything that matches the
-// given matcher.
-template <typename M>
-inline internal::MatcherAsPredicate<M> Matches(M matcher) {
-  return internal::MatcherAsPredicate<M>(matcher);
-}
-
-// Returns true iff the value matches the matcher.
-template <typename T, typename M>
-inline bool Value(const T& value, M matcher) {
-  return testing::Matches(matcher)(value);
-}
-
-// Matches the value against the given matcher and explains the match
-// result to listener.
-template <typename T, typename M>
-inline bool ExplainMatchResult(
-    M matcher, const T& value, MatchResultListener* listener) {
-  return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener);
-}
-
-#if GTEST_LANG_CXX11
-// Define variadic matcher versions. They are overloaded in
-// gmock-generated-matchers.h for the cases supported by pre C++11 compilers.
-template <typename... Args>
-inline internal::AllOfMatcher<Args...> AllOf(const Args&... matchers) {
-  return internal::AllOfMatcher<Args...>(matchers...);
-}
-
-template <typename... Args>
-inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) {
-  return internal::AnyOfMatcher<Args...>(matchers...);
-}
-
-#endif  // GTEST_LANG_CXX11
-
-// AllArgs(m) is a synonym of m.  This is useful in
-//
-//   EXPECT_CALL(foo, Bar(_, _)).With(AllArgs(Eq()));
-//
-// which is easier to read than
-//
-//   EXPECT_CALL(foo, Bar(_, _)).With(Eq());
-template <typename InnerMatcher>
-inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
-
-// These macros allow using matchers to check values in Google Test
-// tests.  ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
-// succeed iff the value matches the matcher.  If the assertion fails,
-// the value and the description of the matcher will be printed.
-#define ASSERT_THAT(value, matcher) ASSERT_PRED_FORMAT1(\
-    ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
-#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\
-    ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
-
-}  // namespace testing
-
-// Include any custom callback matchers added by the local installation.
-// We must include this header at the end to make sure it can use the
-// declarations from this file.
-// Copyright 2015, 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.
-//
-// ============================================================
-// An installation-specific extension point for gmock-matchers.h.
-// ============================================================
-//
-// Adds google3 callback support to CallableTraits.
-//
-#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_
-#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_
-
-#endif  //  GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_
-#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
-
-namespace testing {
-
-// An abstract handle of an expectation.
-class Expectation;
-
-// A set of expectation handles.
-class ExpectationSet;
-
-// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
-// and MUST NOT BE USED IN USER CODE!!!
-namespace internal {
-
-// Implements a mock function.
-template <typename F> class FunctionMocker;
-
-// Base class for expectations.
-class ExpectationBase;
-
-// Implements an expectation.
-template <typename F> class TypedExpectation;
-
-// Helper class for testing the Expectation class template.
-class ExpectationTester;
-
-// Base class for function mockers.
-template <typename F> class FunctionMockerBase;
-
-// Protects the mock object registry (in class Mock), all function
-// mockers, and all expectations.
-//
-// The reason we don't use more fine-grained protection is: when a
-// mock function Foo() is called, it needs to consult its expectations
-// to see which one should be picked.  If another thread is allowed to
-// call a mock function (either Foo() or a different one) at the same
-// time, it could affect the "retired" attributes of Foo()'s
-// expectations when InSequence() is used, and thus affect which
-// expectation gets picked.  Therefore, we sequence all mock function
-// calls to ensure the integrity of the mock objects' states.
-GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex);
-
-// Untyped base class for ActionResultHolder<R>.
-class UntypedActionResultHolderBase;
-
-// Abstract base class of FunctionMockerBase.  This is the
-// type-agnostic part of the function mocker interface.  Its pure
-// virtual methods are implemented by FunctionMockerBase.
-class GTEST_API_ UntypedFunctionMockerBase {
- public:
-  UntypedFunctionMockerBase();
-  virtual ~UntypedFunctionMockerBase();
-
-  // Verifies that all expectations on this mock function have been
-  // satisfied.  Reports one or more Google Test non-fatal failures
-  // and returns false if not.
-  bool VerifyAndClearExpectationsLocked()
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
-
-  // Clears the ON_CALL()s set on this mock function.
-  virtual void ClearDefaultActionsLocked()
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) = 0;
-
-  // In all of the following Untyped* functions, it's the caller's
-  // responsibility to guarantee the correctness of the arguments'
-  // types.
-
-  // Performs the default action with the given arguments and returns
-  // the action's result.  The call description string will be used in
-  // the error message to describe the call in the case the default
-  // action fails.
-  // L = *
-  virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
-      const void* untyped_args,
-      const string& call_description) const = 0;
-
-  // Performs the given action with the given arguments and returns
-  // the action's result.
-  // L = *
-  virtual UntypedActionResultHolderBase* UntypedPerformAction(
-      const void* untyped_action,
-      const void* untyped_args) const = 0;
-
-  // Writes a message that the call is uninteresting (i.e. neither
-  // explicitly expected nor explicitly unexpected) to the given
-  // ostream.
-  virtual void UntypedDescribeUninterestingCall(
-      const void* untyped_args,
-      ::std::ostream* os) const
-          GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;
-
-  // Returns the expectation that matches the given function arguments
-  // (or NULL is there's no match); when a match is found,
-  // untyped_action is set to point to the action that should be
-  // performed (or NULL if the action is "do default"), and
-  // is_excessive is modified to indicate whether the call exceeds the
-  // expected number.
-  virtual const ExpectationBase* UntypedFindMatchingExpectation(
-      const void* untyped_args,
-      const void** untyped_action, bool* is_excessive,
-      ::std::ostream* what, ::std::ostream* why)
-          GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0;
-
-  // Prints the given function arguments to the ostream.
-  virtual void UntypedPrintArgs(const void* untyped_args,
-                                ::std::ostream* os) const = 0;
-
-  // Sets the mock object this mock method belongs to, and registers
-  // this information in the global mock registry.  Will be called
-  // whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
-  // method.
-  // TODO(wan@google.com): rename to SetAndRegisterOwner().
-  void RegisterOwner(const void* mock_obj)
-      GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
-
-  // Sets the mock object this mock method belongs to, and sets the
-  // name of the mock function.  Will be called upon each invocation
-  // of this mock function.
-  void SetOwnerAndName(const void* mock_obj, const char* name)
-      GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
-
-  // Returns the mock object this mock method belongs to.  Must be
-  // called after RegisterOwner() or SetOwnerAndName() has been
-  // called.
-  const void* MockObject() const
-      GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
-
-  // Returns the name of this mock method.  Must be called after
-  // SetOwnerAndName() has been called.
-  const char* Name() const
-      GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
-
-  // Returns the result of invoking this mock function with the given
-  // arguments.  This function can be safely called from multiple
-  // threads concurrently.  The caller is responsible for deleting the
-  // result.
-  UntypedActionResultHolderBase* UntypedInvokeWith(
-      const void* untyped_args)
-          GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
-
- protected:
-  typedef std::vector<const void*> UntypedOnCallSpecs;
-
-  typedef std::vector<internal::linked_ptr<ExpectationBase> >
-  UntypedExpectations;
-
-  // Returns an Expectation object that references and co-owns exp,
-  // which must be an expectation on this mock function.
-  Expectation GetHandleOf(ExpectationBase* exp);
-
-  // Address of the mock object this mock method belongs to.  Only
-  // valid after this mock method has been called or
-  // ON_CALL/EXPECT_CALL has been invoked on it.
-  const void* mock_obj_;  // Protected by g_gmock_mutex.
-
-  // Name of the function being mocked.  Only valid after this mock
-  // method has been called.
-  const char* name_;  // Protected by g_gmock_mutex.
-
-  // All default action specs for this function mocker.
-  UntypedOnCallSpecs untyped_on_call_specs_;
-
-  // All expectations for this function mocker.
-  UntypedExpectations untyped_expectations_;
-};  // class UntypedFunctionMockerBase
-
-// Untyped base class for OnCallSpec<F>.
-class UntypedOnCallSpecBase {
- public:
-  // The arguments are the location of the ON_CALL() statement.
-  UntypedOnCallSpecBase(const char* a_file, int a_line)
-      : file_(a_file), line_(a_line), last_clause_(kNone) {}
-
-  // Where in the source file was the default action spec defined?
-  const char* file() const { return file_; }
-  int line() const { return line_; }
-
- protected:
-  // Gives each clause in the ON_CALL() statement a name.
-  enum Clause {
-    // Do not change the order of the enum members!  The run-time
-    // syntax checking relies on it.
-    kNone,
-    kWith,
-    kWillByDefault
-  };
-
-  // Asserts that the ON_CALL() statement has a certain property.
-  void AssertSpecProperty(bool property, const string& failure_message) const {
-    Assert(property, file_, line_, failure_message);
-  }
-
-  // Expects that the ON_CALL() statement has a certain property.
-  void ExpectSpecProperty(bool property, const string& failure_message) const {
-    Expect(property, file_, line_, failure_message);
-  }
-
-  const char* file_;
-  int line_;
-
-  // The last clause in the ON_CALL() statement as seen so far.
-  // Initially kNone and changes as the statement is parsed.
-  Clause last_clause_;
-};  // class UntypedOnCallSpecBase
-
-// This template class implements an ON_CALL spec.
-template <typename F>
-class OnCallSpec : public UntypedOnCallSpecBase {
- public:
-  typedef typename Function<F>::ArgumentTuple ArgumentTuple;
-  typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
-
-  // Constructs an OnCallSpec object from the information inside
-  // the parenthesis of an ON_CALL() statement.
-  OnCallSpec(const char* a_file, int a_line,
-             const ArgumentMatcherTuple& matchers)
-      : UntypedOnCallSpecBase(a_file, a_line),
-        matchers_(matchers),
-        // By default, extra_matcher_ should match anything.  However,
-        // we cannot initialize it with _ as that triggers a compiler
-        // bug in Symbian's C++ compiler (cannot decide between two
-        // overloaded constructors of Matcher<const ArgumentTuple&>).
-        extra_matcher_(A<const ArgumentTuple&>()) {
-  }
-
-  // Implements the .With() clause.
-  OnCallSpec& With(const Matcher<const ArgumentTuple&>& m) {
-    // Makes sure this is called at most once.
-    ExpectSpecProperty(last_clause_ < kWith,
-                       ".With() cannot appear "
-                       "more than once in an ON_CALL().");
-    last_clause_ = kWith;
-
-    extra_matcher_ = m;
-    return *this;
-  }
-
-  // Implements the .WillByDefault() clause.
-  OnCallSpec& WillByDefault(const Action<F>& action) {
-    ExpectSpecProperty(last_clause_ < kWillByDefault,
-                       ".WillByDefault() must appear "
-                       "exactly once in an ON_CALL().");
-    last_clause_ = kWillByDefault;
-
-    ExpectSpecProperty(!action.IsDoDefault(),
-                       "DoDefault() cannot be used in ON_CALL().");
-    action_ = action;
-    return *this;
-  }
-
-  // Returns true iff the given arguments match the matchers.
-  bool Matches(const ArgumentTuple& args) const {
-    return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);
-  }
-
-  // Returns the action specified by the user.
-  const Action<F>& GetAction() const {
-    AssertSpecProperty(last_clause_ == kWillByDefault,
-                       ".WillByDefault() must appear exactly "
-                       "once in an ON_CALL().");
-    return action_;
-  }
-
- private:
-  // The information in statement
-  //
-  //   ON_CALL(mock_object, Method(matchers))
-  //       .With(multi-argument-matcher)
-  //       .WillByDefault(action);
-  //
-  // is recorded in the data members like this:
-  //
-  //   source file that contains the statement => file_
-  //   line number of the statement            => line_
-  //   matchers                                => matchers_
-  //   multi-argument-matcher                  => extra_matcher_
-  //   action                                  => action_
-  ArgumentMatcherTuple matchers_;
-  Matcher<const ArgumentTuple&> extra_matcher_;
-  Action<F> action_;
-};  // class OnCallSpec
-
-// Possible reactions on uninteresting calls.
-enum CallReaction {
-  kAllow,
-  kWarn,
-  kFail,
-  kDefault = kWarn  // By default, warn about uninteresting calls.
-};
-
-}  // namespace internal
-
-// Utilities for manipulating mock objects.
-class GTEST_API_ Mock {
- public:
-  // The following public methods can be called concurrently.
-
-  // Tells Google Mock to ignore mock_obj when checking for leaked
-  // mock objects.
-  static void AllowLeak(const void* mock_obj)
-      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
-
-  // Verifies and clears all expectations on the given mock object.
-  // If the expectations aren't satisfied, generates one or more
-  // Google Test non-fatal failures and returns false.
-  static bool VerifyAndClearExpectations(void* mock_obj)
-      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
-
-  // Verifies all expectations on the given mock object and clears its
-  // default actions and expectations.  Returns true iff the
-  // verification was successful.
-  static bool VerifyAndClear(void* mock_obj)
-      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
-
- private:
-  friend class internal::UntypedFunctionMockerBase;
-
-  // Needed for a function mocker to register itself (so that we know
-  // how to clear a mock object).
-  template <typename F>
-  friend class internal::FunctionMockerBase;
-
-  template <typename M>
-  friend class NiceMock;
-
-  template <typename M>
-  friend class NaggyMock;
-
-  template <typename M>
-  friend class StrictMock;
-
-  // Tells Google Mock to allow uninteresting calls on the given mock
-  // object.
-  static void AllowUninterestingCalls(const void* mock_obj)
-      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
-
-  // Tells Google Mock to warn the user about uninteresting calls on
-  // the given mock object.
-  static void WarnUninterestingCalls(const void* mock_obj)
-      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
-
-  // Tells Google Mock to fail uninteresting calls on the given mock
-  // object.
-  static void FailUninterestingCalls(const void* mock_obj)
-      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
-
-  // Tells Google Mock the given mock object is being destroyed and
-  // its entry in the call-reaction table should be removed.
-  static void UnregisterCallReaction(const void* mock_obj)
-      GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
-
-  // Returns the reaction Google Mock will have on uninteresting calls
-  // made on the given mock object.
-  static internal::CallReaction GetReactionOnUninterestingCalls(
-      const void* mock_obj)
-          GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
-
-  // Verifies that all expectations on the given mock object have been
-  // satisfied.  Reports one or more Google Test non-fatal failures
-  // and returns false if not.
-  static bool VerifyAndClearExpectationsLocked(void* mock_obj)
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
-
-  // Clears all ON_CALL()s set on the given mock object.
-  static void ClearDefaultActionsLocked(void* mock_obj)
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
-
-  // Registers a mock object and a mock method it owns.
-  static void Register(
-      const void* mock_obj,
-      internal::UntypedFunctionMockerBase* mocker)
-          GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
-
-  // Tells Google Mock where in the source code mock_obj is used in an
-  // ON_CALL or EXPECT_CALL.  In case mock_obj is leaked, this
-  // information helps the user identify which object it is.
-  static void RegisterUseByOnCallOrExpectCall(
-      const void* mock_obj, const char* file, int line)
-          GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
-
-  // Unregisters a mock method; removes the owning mock object from
-  // the registry when the last mock method associated with it has
-  // been unregistered.  This is called only in the destructor of
-  // FunctionMockerBase.
-  static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
-};  // class Mock
-
-// An abstract handle of an expectation.  Useful in the .After()
-// clause of EXPECT_CALL() for setting the (partial) order of
-// expectations.  The syntax:
-//
-//   Expectation e1 = EXPECT_CALL(...)...;
-//   EXPECT_CALL(...).After(e1)...;
-//
-// sets two expectations where the latter can only be matched after
-// the former has been satisfied.
-//
-// Notes:
-//   - This class is copyable and has value semantics.
-//   - Constness is shallow: a const Expectation object itself cannot
-//     be modified, but the mutable methods of the ExpectationBase
-//     object it references can be called via expectation_base().
-//   - The constructors and destructor are defined out-of-line because
-//     the Symbian WINSCW compiler wants to otherwise instantiate them
-//     when it sees this class definition, at which point it doesn't have
-//     ExpectationBase available yet, leading to incorrect destruction
-//     in the linked_ptr (or compilation errors if using a checking
-//     linked_ptr).
-class GTEST_API_ Expectation {
- public:
-  // Constructs a null object that doesn't reference any expectation.
-  Expectation();
-
-  ~Expectation();
-
-  // This single-argument ctor must not be explicit, in order to support the
-  //   Expectation e = EXPECT_CALL(...);
-  // syntax.
-  //
-  // A TypedExpectation object stores its pre-requisites as
-  // Expectation objects, and needs to call the non-const Retire()
-  // method on the ExpectationBase objects they reference.  Therefore
-  // Expectation must receive a *non-const* reference to the
-  // ExpectationBase object.
-  Expectation(internal::ExpectationBase& exp);  // NOLINT
-
-  // The compiler-generated copy ctor and operator= work exactly as
-  // intended, so we don't need to define our own.
-
-  // Returns true iff rhs references the same expectation as this object does.
-  bool operator==(const Expectation& rhs) const {
-    return expectation_base_ == rhs.expectation_base_;
-  }
-
-  bool operator!=(const Expectation& rhs) const { return !(*this == rhs); }
-
- private:
-  friend class ExpectationSet;
-  friend class Sequence;
-  friend class ::testing::internal::ExpectationBase;
-  friend class ::testing::internal::UntypedFunctionMockerBase;
-
-  template <typename F>
-  friend class ::testing::internal::FunctionMockerBase;
-
-  template <typename F>
-  friend class ::testing::internal::TypedExpectation;
-
-  // This comparator is needed for putting Expectation objects into a set.
-  class Less {
-   public:
-    bool operator()(const Expectation& lhs, const Expectation& rhs) const {
-      return lhs.expectation_base_.get() < rhs.expectation_base_.get();
-    }
-  };
-
-  typedef ::std::set<Expectation, Less> Set;
-
-  Expectation(
-      const internal::linked_ptr<internal::ExpectationBase>& expectation_base);
-
-  // Returns the expectation this object references.
-  const internal::linked_ptr<internal::ExpectationBase>&
-  expectation_base() const {
-    return expectation_base_;
-  }
-
-  // A linked_ptr that co-owns the expectation this handle references.
-  internal::linked_ptr<internal::ExpectationBase> expectation_base_;
-};
-
-// A set of expectation handles.  Useful in the .After() clause of
-// EXPECT_CALL() for setting the (partial) order of expectations.  The
-// syntax:
-//
-//   ExpectationSet es;
-//   es += EXPECT_CALL(...)...;
-//   es += EXPECT_CALL(...)...;
-//   EXPECT_CALL(...).After(es)...;
-//
-// sets three expectations where the last one can only be matched
-// after the first two have both been satisfied.
-//
-// This class is copyable and has value semantics.
-class ExpectationSet {
- public:
-  // A bidirectional iterator that can read a const element in the set.
-  typedef Expectation::Set::const_iterator const_iterator;
-
-  // An object stored in the set.  This is an alias of Expectation.
-  typedef Expectation::Set::value_type value_type;
-
-  // Constructs an empty set.
-  ExpectationSet() {}
-
-  // This single-argument ctor must not be explicit, in order to support the
-  //   ExpectationSet es = EXPECT_CALL(...);
-  // syntax.
-  ExpectationSet(internal::ExpectationBase& exp) {  // NOLINT
-    *this += Expectation(exp);
-  }
-
-  // This single-argument ctor implements implicit conversion from
-  // Expectation and thus must not be explicit.  This allows either an
-  // Expectation or an ExpectationSet to be used in .After().
-  ExpectationSet(const Expectation& e) {  // NOLINT
-    *this += e;
-  }
-
-  // The compiler-generator ctor and operator= works exactly as
-  // intended, so we don't need to define our own.
-
-  // Returns true iff rhs contains the same set of Expectation objects
-  // as this does.
-  bool operator==(const ExpectationSet& rhs) const {
-    return expectations_ == rhs.expectations_;
-  }
-
-  bool operator!=(const ExpectationSet& rhs) const { return !(*this == rhs); }
-
-  // Implements the syntax
-  //   expectation_set += EXPECT_CALL(...);
-  ExpectationSet& operator+=(const Expectation& e) {
-    expectations_.insert(e);
-    return *this;
-  }
-
-  int size() const { return static_cast<int>(expectations_.size()); }
-
-  const_iterator begin() const { return expectations_.begin(); }
-  const_iterator end() const { return expectations_.end(); }
-
- private:
-  Expectation::Set expectations_;
-};
-
-
-// Sequence objects are used by a user to specify the relative order
-// in which the expectations should match.  They are copyable (we rely
-// on the compiler-defined copy constructor and assignment operator).
-class GTEST_API_ Sequence {
- public:
-  // Constructs an empty sequence.
-  Sequence() : last_expectation_(new Expectation) {}
-
-  // Adds an expectation to this sequence.  The caller must ensure
-  // that no other thread is accessing this Sequence object.
-  void AddExpectation(const Expectation& expectation) const;
-
- private:
-  // The last expectation in this sequence.  We use a linked_ptr here
-  // because Sequence objects are copyable and we want the copies to
-  // be aliases.  The linked_ptr allows the copies to co-own and share
-  // the same Expectation object.
-  internal::linked_ptr<Expectation> last_expectation_;
-};  // class Sequence
-
-// An object of this type causes all EXPECT_CALL() statements
-// encountered in its scope to be put in an anonymous sequence.  The
-// work is done in the constructor and destructor.  You should only
-// create an InSequence object on the stack.
-//
-// The sole purpose for this class is to support easy definition of
-// sequential expectations, e.g.
-//
-//   {
-//     InSequence dummy;  // The name of the object doesn't matter.
-//
-//     // The following expectations must match in the order they appear.
-//     EXPECT_CALL(a, Bar())...;
-//     EXPECT_CALL(a, Baz())...;
-//     ...
-//     EXPECT_CALL(b, Xyz())...;
-//   }
-//
-// You can create InSequence objects in multiple threads, as long as
-// they are used to affect different mock objects.  The idea is that
-// each thread can create and set up its own mocks as if it's the only
-// thread.  However, for clarity of your tests we recommend you to set
-// up mocks in the main thread unless you have a good reason not to do
-// so.
-class GTEST_API_ InSequence {
- public:
-  InSequence();
-  ~InSequence();
- private:
-  bool sequence_created_;
-
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(InSequence);  // NOLINT
-} GTEST_ATTRIBUTE_UNUSED_;
-
-namespace internal {
-
-// Points to the implicit sequence introduced by a living InSequence
-// object (if any) in the current thread or NULL.
-GTEST_API_ extern ThreadLocal<Sequence*> g_gmock_implicit_sequence;
-
-// Base class for implementing expectations.
-//
-// There are two reasons for having a type-agnostic base class for
-// Expectation:
-//
-//   1. We need to store collections of expectations of different
-//   types (e.g. all pre-requisites of a particular expectation, all
-//   expectations in a sequence).  Therefore these expectation objects
-//   must share a common base class.
-//
-//   2. We can avoid binary code bloat by moving methods not depending
-//   on the template argument of Expectation to the base class.
-//
-// This class is internal and mustn't be used by user code directly.
-class GTEST_API_ ExpectationBase {
- public:
-  // source_text is the EXPECT_CALL(...) source that created this Expectation.
-  ExpectationBase(const char* file, int line, const string& source_text);
-
-  virtual ~ExpectationBase();
-
-  // Where in the source file was the expectation spec defined?
-  const char* file() const { return file_; }
-  int line() const { return line_; }
-  const char* source_text() const { return source_text_.c_str(); }
-  // Returns the cardinality specified in the expectation spec.
-  const Cardinality& cardinality() const { return cardinality_; }
-
-  // Describes the source file location of this expectation.
-  void DescribeLocationTo(::std::ostream* os) const {
-    *os << FormatFileLocation(file(), line()) << " ";
-  }
-
-  // Describes how many times a function call matching this
-  // expectation has occurred.
-  void DescribeCallCountTo(::std::ostream* os) const
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
-
-  // If this mock method has an extra matcher (i.e. .With(matcher)),
-  // describes it to the ostream.
-  virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) = 0;
-
- protected:
-  friend class ::testing::Expectation;
-  friend class UntypedFunctionMockerBase;
-
-  enum Clause {
-    // Don't change the order of the enum members!
-    kNone,
-    kWith,
-    kTimes,
-    kInSequence,
-    kAfter,
-    kWillOnce,
-    kWillRepeatedly,
-    kRetiresOnSaturation
-  };
-
-  typedef std::vector<const void*> UntypedActions;
-
-  // Returns an Expectation object that references and co-owns this
-  // expectation.
-  virtual Expectation GetHandle() = 0;
-
-  // Asserts that the EXPECT_CALL() statement has the given property.
-  void AssertSpecProperty(bool property, const string& failure_message) const {
-    Assert(property, file_, line_, failure_message);
-  }
-
-  // Expects that the EXPECT_CALL() statement has the given property.
-  void ExpectSpecProperty(bool property, const string& failure_message) const {
-    Expect(property, file_, line_, failure_message);
-  }
-
-  // Explicitly specifies the cardinality of this expectation.  Used
-  // by the subclasses to implement the .Times() clause.
-  void SpecifyCardinality(const Cardinality& cardinality);
-
-  // Returns true iff the user specified the cardinality explicitly
-  // using a .Times().
-  bool cardinality_specified() const { return cardinality_specified_; }
-
-  // Sets the cardinality of this expectation spec.
-  void set_cardinality(const Cardinality& a_cardinality) {
-    cardinality_ = a_cardinality;
-  }
-
-  // The following group of methods should only be called after the
-  // EXPECT_CALL() statement, and only when g_gmock_mutex is held by
-  // the current thread.
-
-  // Retires all pre-requisites of this expectation.
-  void RetireAllPreRequisites()
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
-
-  // Returns true iff this expectation is retired.
-  bool is_retired() const
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-    return retired_;
-  }
-
-  // Retires this expectation.
-  void Retire()
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-    retired_ = true;
-  }
-
-  // Returns true iff this expectation is satisfied.
-  bool IsSatisfied() const
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-    return cardinality().IsSatisfiedByCallCount(call_count_);
-  }
-
-  // Returns true iff this expectation is saturated.
-  bool IsSaturated() const
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-    return cardinality().IsSaturatedByCallCount(call_count_);
-  }
-
-  // Returns true iff this expectation is over-saturated.
-  bool IsOverSaturated() const
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-    return cardinality().IsOverSaturatedByCallCount(call_count_);
-  }
-
-  // Returns true iff all pre-requisites of this expectation are satisfied.
-  bool AllPrerequisitesAreSatisfied() const
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
-
-  // Adds unsatisfied pre-requisites of this expectation to 'result'.
-  void FindUnsatisfiedPrerequisites(ExpectationSet* result) const
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
-
-  // Returns the number this expectation has been invoked.
-  int call_count() const
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-    return call_count_;
-  }
-
-  // Increments the number this expectation has been invoked.
-  void IncrementCallCount()
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-    call_count_++;
-  }
-
-  // Checks the action count (i.e. the number of WillOnce() and
-  // WillRepeatedly() clauses) against the cardinality if this hasn't
-  // been done before.  Prints a warning if there are too many or too
-  // few actions.
-  void CheckActionCountIfNotDone() const
-      GTEST_LOCK_EXCLUDED_(mutex_);
-
-  friend class ::testing::Sequence;
-  friend class ::testing::internal::ExpectationTester;
-
-  template <typename Function>
-  friend class TypedExpectation;
-
-  // Implements the .Times() clause.
-  void UntypedTimes(const Cardinality& a_cardinality);
-
-  // This group of fields are part of the spec and won't change after
-  // an EXPECT_CALL() statement finishes.
-  const char* file_;          // The file that contains the expectation.
-  int line_;                  // The line number of the expectation.
-  const string source_text_;  // The EXPECT_CALL(...) source text.
-  // True iff the cardinality is specified explicitly.
-  bool cardinality_specified_;
-  Cardinality cardinality_;            // The cardinality of the expectation.
-  // The immediate pre-requisites (i.e. expectations that must be
-  // satisfied before this expectation can be matched) of this
-  // expectation.  We use linked_ptr in the set because we want an
-  // Expectation object to be co-owned by its FunctionMocker and its
-  // successors.  This allows multiple mock objects to be deleted at
-  // different times.
-  ExpectationSet immediate_prerequisites_;
-
-  // This group of fields are the current state of the expectation,
-  // and can change as the mock function is called.
-  int call_count_;  // How many times this expectation has been invoked.
-  bool retired_;    // True iff this expectation has retired.
-  UntypedActions untyped_actions_;
-  bool extra_matcher_specified_;
-  bool repeated_action_specified_;  // True if a WillRepeatedly() was specified.
-  bool retires_on_saturation_;
-  Clause last_clause_;
-  mutable bool action_count_checked_;  // Under mutex_.
-  mutable Mutex mutex_;  // Protects action_count_checked_.
-
-  GTEST_DISALLOW_ASSIGN_(ExpectationBase);
-};  // class ExpectationBase
-
-// Impements an expectation for the given function type.
-template <typename F>
-class TypedExpectation : public ExpectationBase {
- public:
-  typedef typename Function<F>::ArgumentTuple ArgumentTuple;
-  typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
-  typedef typename Function<F>::Result Result;
-
-  TypedExpectation(FunctionMockerBase<F>* owner,
-                   const char* a_file, int a_line, const string& a_source_text,
-                   const ArgumentMatcherTuple& m)
-      : ExpectationBase(a_file, a_line, a_source_text),
-        owner_(owner),
-        matchers_(m),
-        // By default, extra_matcher_ should match anything.  However,
-        // we cannot initialize it with _ as that triggers a compiler
-        // bug in Symbian's C++ compiler (cannot decide between two
-        // overloaded constructors of Matcher<const ArgumentTuple&>).
-        extra_matcher_(A<const ArgumentTuple&>()),
-        repeated_action_(DoDefault()) {}
-
-  virtual ~TypedExpectation() {
-    // Check the validity of the action count if it hasn't been done
-    // yet (for example, if the expectation was never used).
-    CheckActionCountIfNotDone();
-    for (UntypedActions::const_iterator it = untyped_actions_.begin();
-         it != untyped_actions_.end(); ++it) {
-      delete static_cast<const Action<F>*>(*it);
-    }
-  }
-
-  // Implements the .With() clause.
-  TypedExpectation& With(const Matcher<const ArgumentTuple&>& m) {
-    if (last_clause_ == kWith) {
-      ExpectSpecProperty(false,
-                         ".With() cannot appear "
-                         "more than once in an EXPECT_CALL().");
-    } else {
-      ExpectSpecProperty(last_clause_ < kWith,
-                         ".With() must be the first "
-                         "clause in an EXPECT_CALL().");
-    }
-    last_clause_ = kWith;
-
-    extra_matcher_ = m;
-    extra_matcher_specified_ = true;
-    return *this;
-  }
-
-  // Implements the .Times() clause.
-  TypedExpectation& Times(const Cardinality& a_cardinality) {
-    ExpectationBase::UntypedTimes(a_cardinality);
-    return *this;
-  }
-
-  // Implements the .Times() clause.
-  TypedExpectation& Times(int n) {
-    return Times(Exactly(n));
-  }
-
-  // Implements the .InSequence() clause.
-  TypedExpectation& InSequence(const Sequence& s) {
-    ExpectSpecProperty(last_clause_ <= kInSequence,
-                       ".InSequence() cannot appear after .After(),"
-                       " .WillOnce(), .WillRepeatedly(), or "
-                       ".RetiresOnSaturation().");
-    last_clause_ = kInSequence;
-
-    s.AddExpectation(GetHandle());
-    return *this;
-  }
-  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2) {
-    return InSequence(s1).InSequence(s2);
-  }
-  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,
-                               const Sequence& s3) {
-    return InSequence(s1, s2).InSequence(s3);
-  }
-  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,
-                               const Sequence& s3, const Sequence& s4) {
-    return InSequence(s1, s2, s3).InSequence(s4);
-  }
-  TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2,
-                               const Sequence& s3, const Sequence& s4,
-                               const Sequence& s5) {
-    return InSequence(s1, s2, s3, s4).InSequence(s5);
-  }
-
-  // Implements that .After() clause.
-  TypedExpectation& After(const ExpectationSet& s) {
-    ExpectSpecProperty(last_clause_ <= kAfter,
-                       ".After() cannot appear after .WillOnce(),"
-                       " .WillRepeatedly(), or "
-                       ".RetiresOnSaturation().");
-    last_clause_ = kAfter;
-
-    for (ExpectationSet::const_iterator it = s.begin(); it != s.end(); ++it) {
-      immediate_prerequisites_ += *it;
-    }
-    return *this;
-  }
-  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2) {
-    return After(s1).After(s2);
-  }
-  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,
-                          const ExpectationSet& s3) {
-    return After(s1, s2).After(s3);
-  }
-  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,
-                          const ExpectationSet& s3, const ExpectationSet& s4) {
-    return After(s1, s2, s3).After(s4);
-  }
-  TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2,
-                          const ExpectationSet& s3, const ExpectationSet& s4,
-                          const ExpectationSet& s5) {
-    return After(s1, s2, s3, s4).After(s5);
-  }
-
-  // Implements the .WillOnce() clause.
-  TypedExpectation& WillOnce(const Action<F>& action) {
-    ExpectSpecProperty(last_clause_ <= kWillOnce,
-                       ".WillOnce() cannot appear after "
-                       ".WillRepeatedly() or .RetiresOnSaturation().");
-    last_clause_ = kWillOnce;
-
-    untyped_actions_.push_back(new Action<F>(action));
-    if (!cardinality_specified()) {
-      set_cardinality(Exactly(static_cast<int>(untyped_actions_.size())));
-    }
-    return *this;
-  }
-
-  // Implements the .WillRepeatedly() clause.
-  TypedExpectation& WillRepeatedly(const Action<F>& action) {
-    if (last_clause_ == kWillRepeatedly) {
-      ExpectSpecProperty(false,
-                         ".WillRepeatedly() cannot appear "
-                         "more than once in an EXPECT_CALL().");
-    } else {
-      ExpectSpecProperty(last_clause_ < kWillRepeatedly,
-                         ".WillRepeatedly() cannot appear "
-                         "after .RetiresOnSaturation().");
-    }
-    last_clause_ = kWillRepeatedly;
-    repeated_action_specified_ = true;
-
-    repeated_action_ = action;
-    if (!cardinality_specified()) {
-      set_cardinality(AtLeast(static_cast<int>(untyped_actions_.size())));
-    }
-
-    // Now that no more action clauses can be specified, we check
-    // whether their count makes sense.
-    CheckActionCountIfNotDone();
-    return *this;
-  }
-
-  // Implements the .RetiresOnSaturation() clause.
-  TypedExpectation& RetiresOnSaturation() {
-    ExpectSpecProperty(last_clause_ < kRetiresOnSaturation,
-                       ".RetiresOnSaturation() cannot appear "
-                       "more than once.");
-    last_clause_ = kRetiresOnSaturation;
-    retires_on_saturation_ = true;
-
-    // Now that no more action clauses can be specified, we check
-    // whether their count makes sense.
-    CheckActionCountIfNotDone();
-    return *this;
-  }
-
-  // Returns the matchers for the arguments as specified inside the
-  // EXPECT_CALL() macro.
-  const ArgumentMatcherTuple& matchers() const {
-    return matchers_;
-  }
-
-  // Returns the matcher specified by the .With() clause.
-  const Matcher<const ArgumentTuple&>& extra_matcher() const {
-    return extra_matcher_;
-  }
-
-  // Returns the action specified by the .WillRepeatedly() clause.
-  const Action<F>& repeated_action() const { return repeated_action_; }
-
-  // If this mock method has an extra matcher (i.e. .With(matcher)),
-  // describes it to the ostream.
-  virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) {
-    if (extra_matcher_specified_) {
-      *os << "    Expected args: ";
-      extra_matcher_.DescribeTo(os);
-      *os << "\n";
-    }
-  }
-
- private:
-  template <typename Function>
-  friend class FunctionMockerBase;
-
-  // Returns an Expectation object that references and co-owns this
-  // expectation.
-  virtual Expectation GetHandle() {
-    return owner_->GetHandleOf(this);
-  }
-
-  // The following methods will be called only after the EXPECT_CALL()
-  // statement finishes and when the current thread holds
-  // g_gmock_mutex.
-
-  // Returns true iff this expectation matches the given arguments.
-  bool Matches(const ArgumentTuple& args) const
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-    return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);
-  }
-
-  // Returns true iff this expectation should handle the given arguments.
-  bool ShouldHandleArguments(const ArgumentTuple& args) const
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-
-    // In case the action count wasn't checked when the expectation
-    // was defined (e.g. if this expectation has no WillRepeatedly()
-    // or RetiresOnSaturation() clause), we check it when the
-    // expectation is used for the first time.
-    CheckActionCountIfNotDone();
-    return !is_retired() && AllPrerequisitesAreSatisfied() && Matches(args);
-  }
-
-  // Describes the result of matching the arguments against this
-  // expectation to the given ostream.
-  void ExplainMatchResultTo(
-      const ArgumentTuple& args,
-      ::std::ostream* os) const
-          GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-
-    if (is_retired()) {
-      *os << "         Expected: the expectation is active\n"
-          << "           Actual: it is retired\n";
-    } else if (!Matches(args)) {
-      if (!TupleMatches(matchers_, args)) {
-        ExplainMatchFailureTupleTo(matchers_, args, os);
-      }
-      StringMatchResultListener listener;
-      if (!extra_matcher_.MatchAndExplain(args, &listener)) {
-        *os << "    Expected args: ";
-        extra_matcher_.DescribeTo(os);
-        *os << "\n           Actual: don't match";
-
-        internal::PrintIfNotEmpty(listener.str(), os);
-        *os << "\n";
-      }
-    } else if (!AllPrerequisitesAreSatisfied()) {
-      *os << "         Expected: all pre-requisites are satisfied\n"
-          << "           Actual: the following immediate pre-requisites "
-          << "are not satisfied:\n";
-      ExpectationSet unsatisfied_prereqs;
-      FindUnsatisfiedPrerequisites(&unsatisfied_prereqs);
-      int i = 0;
-      for (ExpectationSet::const_iterator it = unsatisfied_prereqs.begin();
-           it != unsatisfied_prereqs.end(); ++it) {
-        it->expectation_base()->DescribeLocationTo(os);
-        *os << "pre-requisite #" << i++ << "\n";
-      }
-      *os << "                   (end of pre-requisites)\n";
-    } else {
-      // This line is here just for completeness' sake.  It will never
-      // be executed as currently the ExplainMatchResultTo() function
-      // is called only when the mock function call does NOT match the
-      // expectation.
-      *os << "The call matches the expectation.\n";
-    }
-  }
-
-  // Returns the action that should be taken for the current invocation.
-  const Action<F>& GetCurrentAction(
-      const FunctionMockerBase<F>* mocker,
-      const ArgumentTuple& args) const
-          GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-    const int count = call_count();
-    Assert(count >= 1, __FILE__, __LINE__,
-           "call_count() is <= 0 when GetCurrentAction() is "
-           "called - this should never happen.");
-
-    const int action_count = static_cast<int>(untyped_actions_.size());
-    if (action_count > 0 && !repeated_action_specified_ &&
-        count > action_count) {
-      // If there is at least one WillOnce() and no WillRepeatedly(),
-      // we warn the user when the WillOnce() clauses ran out.
-      ::std::stringstream ss;
-      DescribeLocationTo(&ss);
-      ss << "Actions ran out in " << source_text() << "...\n"
-         << "Called " << count << " times, but only "
-         << action_count << " WillOnce()"
-         << (action_count == 1 ? " is" : "s are") << " specified - ";
-      mocker->DescribeDefaultActionTo(args, &ss);
-      Log(kWarning, ss.str(), 1);
-    }
-
-    return count <= action_count ?
-        *static_cast<const Action<F>*>(untyped_actions_[count - 1]) :
-        repeated_action();
-  }
-
-  // Given the arguments of a mock function call, if the call will
-  // over-saturate this expectation, returns the default action;
-  // otherwise, returns the next action in this expectation.  Also
-  // describes *what* happened to 'what', and explains *why* Google
-  // Mock does it to 'why'.  This method is not const as it calls
-  // IncrementCallCount().  A return value of NULL means the default
-  // action.
-  const Action<F>* GetActionForArguments(
-      const FunctionMockerBase<F>* mocker,
-      const ArgumentTuple& args,
-      ::std::ostream* what,
-      ::std::ostream* why)
-          GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-    if (IsSaturated()) {
-      // We have an excessive call.
-      IncrementCallCount();
-      *what << "Mock function called more times than expected - ";
-      mocker->DescribeDefaultActionTo(args, what);
-      DescribeCallCountTo(why);
-
-      // TODO(wan@google.com): allow the user to control whether
-      // unexpected calls should fail immediately or continue using a
-      // flag --gmock_unexpected_calls_are_fatal.
-      return NULL;
-    }
-
-    IncrementCallCount();
-    RetireAllPreRequisites();
-
-    if (retires_on_saturation_ && IsSaturated()) {
-      Retire();
-    }
-
-    // Must be done after IncrementCount()!
-    *what << "Mock function call matches " << source_text() <<"...\n";
-    return &(GetCurrentAction(mocker, args));
-  }
-
-  // All the fields below won't change once the EXPECT_CALL()
-  // statement finishes.
-  FunctionMockerBase<F>* const owner_;
-  ArgumentMatcherTuple matchers_;
-  Matcher<const ArgumentTuple&> extra_matcher_;
-  Action<F> repeated_action_;
-
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(TypedExpectation);
-};  // class TypedExpectation
-
-// A MockSpec object is used by ON_CALL() or EXPECT_CALL() for
-// specifying the default behavior of, or expectation on, a mock
-// function.
-
-// Note: class MockSpec really belongs to the ::testing namespace.
-// However if we define it in ::testing, MSVC will complain when
-// classes in ::testing::internal declare it as a friend class
-// template.  To workaround this compiler bug, we define MockSpec in
-// ::testing::internal and import it into ::testing.
-
-// Logs a message including file and line number information.
-GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
-                                const char* file, int line,
-                                const string& message);
-
-template <typename F>
-class MockSpec {
- public:
-  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-  typedef typename internal::Function<F>::ArgumentMatcherTuple
-      ArgumentMatcherTuple;
-
-  // Constructs a MockSpec object, given the function mocker object
-  // that the spec is associated with.
-  explicit MockSpec(internal::FunctionMockerBase<F>* function_mocker)
-      : function_mocker_(function_mocker) {}
-
-  // Adds a new default action spec to the function mocker and returns
-  // the newly created spec.
-  internal::OnCallSpec<F>& InternalDefaultActionSetAt(
-      const char* file, int line, const char* obj, const char* call) {
-    LogWithLocation(internal::kInfo, file, line,
-        string("ON_CALL(") + obj + ", " + call + ") invoked");
-    return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
-  }
-
-  // Adds a new expectation spec to the function mocker and returns
-  // the newly created spec.
-  internal::TypedExpectation<F>& InternalExpectedAt(
-      const char* file, int line, const char* obj, const char* call) {
-    const string source_text(string("EXPECT_CALL(") + obj + ", " + call + ")");
-    LogWithLocation(internal::kInfo, file, line, source_text + " invoked");
-    return function_mocker_->AddNewExpectation(
-        file, line, source_text, matchers_);
-  }
-
- private:
-  template <typename Function>
-  friend class internal::FunctionMocker;
-
-  void SetMatchers(const ArgumentMatcherTuple& matchers) {
-    matchers_ = matchers;
-  }
-
-  // The function mocker that owns this spec.
-  internal::FunctionMockerBase<F>* const function_mocker_;
-  // The argument matchers specified in the spec.
-  ArgumentMatcherTuple matchers_;
-
-  GTEST_DISALLOW_ASSIGN_(MockSpec);
-};  // class MockSpec
-
-// Wrapper type for generically holding an ordinary value or lvalue reference.
-// If T is not a reference type, it must be copyable or movable.
-// ReferenceOrValueWrapper<T> is movable, and will also be copyable unless
-// T is a move-only value type (which means that it will always be copyable
-// if the current platform does not support move semantics).
-//
-// The primary template defines handling for values, but function header
-// comments describe the contract for the whole template (including
-// specializations).
-template <typename T>
-class ReferenceOrValueWrapper {
- public:
-  // Constructs a wrapper from the given value/reference.
-  explicit ReferenceOrValueWrapper(T value)
-      : value_(::testing::internal::move(value)) {
-  }
-
-  // Unwraps and returns the underlying value/reference, exactly as
-  // originally passed. The behavior of calling this more than once on
-  // the same object is unspecified.
-  T Unwrap() { return ::testing::internal::move(value_); }
-
-  // Provides nondestructive access to the underlying value/reference.
-  // Always returns a const reference (more precisely,
-  // const RemoveReference<T>&). The behavior of calling this after
-  // calling Unwrap on the same object is unspecified.
-  const T& Peek() const {
-    return value_;
-  }
-
- private:
-  T value_;
-};
-
-// Specialization for lvalue reference types. See primary template
-// for documentation.
-template <typename T>
-class ReferenceOrValueWrapper<T&> {
- public:
-  // Workaround for debatable pass-by-reference lint warning (c-library-team
-  // policy precludes NOLINT in this context)
-  typedef T& reference;
-  explicit ReferenceOrValueWrapper(reference ref)
-      : value_ptr_(&ref) {}
-  T& Unwrap() { return *value_ptr_; }
-  const T& Peek() const { return *value_ptr_; }
-
- private:
-  T* value_ptr_;
-};
-
-// MSVC warns about using 'this' in base member initializer list, so
-// we need to temporarily disable the warning.  We have to do it for
-// the entire class to suppress the warning, even though it's about
-// the constructor only.
-
-#ifdef _MSC_VER
-# pragma warning(push)          // Saves the current warning state.
-# pragma warning(disable:4355)  // Temporarily disables warning 4355.
-#endif  // _MSV_VER
-
-// C++ treats the void type specially.  For example, you cannot define
-// a void-typed variable or pass a void value to a function.
-// ActionResultHolder<T> holds a value of type T, where T must be a
-// copyable type or void (T doesn't need to be default-constructable).
-// It hides the syntactic difference between void and other types, and
-// is used to unify the code for invoking both void-returning and
-// non-void-returning mock functions.
-
-// Untyped base class for ActionResultHolder<T>.
-class UntypedActionResultHolderBase {
- public:
-  virtual ~UntypedActionResultHolderBase() {}
-
-  // Prints the held value as an action's result to os.
-  virtual void PrintAsActionResult(::std::ostream* os) const = 0;
-};
-
-// This generic definition is used when T is not void.
-template <typename T>
-class ActionResultHolder : public UntypedActionResultHolderBase {
- public:
-  // Returns the held value. Must not be called more than once.
-  T Unwrap() {
-    return result_.Unwrap();
-  }
-
-  // Prints the held value as an action's result to os.
-  virtual void PrintAsActionResult(::std::ostream* os) const {
-    *os << "\n          Returns: ";
-    // T may be a reference type, so we don't use UniversalPrint().
-    UniversalPrinter<T>::Print(result_.Peek(), os);
-  }
-
-  // Performs the given mock function's default action and returns the
-  // result in a new-ed ActionResultHolder.
-  template <typename F>
-  static ActionResultHolder* PerformDefaultAction(
-      const FunctionMockerBase<F>* func_mocker,
-      const typename Function<F>::ArgumentTuple& args,
-      const string& call_description) {
-    return new ActionResultHolder(Wrapper(
-        func_mocker->PerformDefaultAction(args, call_description)));
-  }
-
-  // Performs the given action and returns the result in a new-ed
-  // ActionResultHolder.
-  template <typename F>
-  static ActionResultHolder*
-  PerformAction(const Action<F>& action,
-                const typename Function<F>::ArgumentTuple& args) {
-    return new ActionResultHolder(Wrapper(action.Perform(args)));
-  }
-
- private:
-  typedef ReferenceOrValueWrapper<T> Wrapper;
-
-  explicit ActionResultHolder(Wrapper result)
-      : result_(::testing::internal::move(result)) {
-  }
-
-  Wrapper result_;
-
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder);
-};
-
-// Specialization for T = void.
-template <>
-class ActionResultHolder<void> : public UntypedActionResultHolderBase {
- public:
-  void Unwrap() { }
-
-  virtual void PrintAsActionResult(::std::ostream* /* os */) const {}
-
-  // Performs the given mock function's default action and returns ownership
-  // of an empty ActionResultHolder*.
-  template <typename F>
-  static ActionResultHolder* PerformDefaultAction(
-      const FunctionMockerBase<F>* func_mocker,
-      const typename Function<F>::ArgumentTuple& args,
-      const string& call_description) {
-    func_mocker->PerformDefaultAction(args, call_description);
-    return new ActionResultHolder;
-  }
-
-  // Performs the given action and returns ownership of an empty
-  // ActionResultHolder*.
-  template <typename F>
-  static ActionResultHolder* PerformAction(
-      const Action<F>& action,
-      const typename Function<F>::ArgumentTuple& args) {
-    action.Perform(args);
-    return new ActionResultHolder;
-  }
-
- private:
-  ActionResultHolder() {}
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder);
-};
-
-// The base of the function mocker class for the given function type.
-// We put the methods in this class instead of its child to avoid code
-// bloat.
-template <typename F>
-class FunctionMockerBase : public UntypedFunctionMockerBase {
- public:
-  typedef typename Function<F>::Result Result;
-  typedef typename Function<F>::ArgumentTuple ArgumentTuple;
-  typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
-
-  FunctionMockerBase() : current_spec_(this) {}
-
-  // The destructor verifies that all expectations on this mock
-  // function have been satisfied.  If not, it will report Google Test
-  // non-fatal failures for the violations.
-  virtual ~FunctionMockerBase()
-        GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
-    MutexLock l(&g_gmock_mutex);
-    VerifyAndClearExpectationsLocked();
-    Mock::UnregisterLocked(this);
-    ClearDefaultActionsLocked();
-  }
-
-  // Returns the ON_CALL spec that matches this mock function with the
-  // given arguments; returns NULL if no matching ON_CALL is found.
-  // L = *
-  const OnCallSpec<F>* FindOnCallSpec(
-      const ArgumentTuple& args) const {
-    for (UntypedOnCallSpecs::const_reverse_iterator it
-             = untyped_on_call_specs_.rbegin();
-         it != untyped_on_call_specs_.rend(); ++it) {
-      const OnCallSpec<F>* spec = static_cast<const OnCallSpec<F>*>(*it);
-      if (spec->Matches(args))
-        return spec;
-    }
-
-    return NULL;
-  }
-
-  // Performs the default action of this mock function on the given
-  // arguments and returns the result. Asserts (or throws if
-  // exceptions are enabled) with a helpful call descrption if there
-  // is no valid return value. This method doesn't depend on the
-  // mutable state of this object, and thus can be called concurrently
-  // without locking.
-  // L = *
-  Result PerformDefaultAction(const ArgumentTuple& args,
-                              const string& call_description) const {
-    const OnCallSpec<F>* const spec =
-        this->FindOnCallSpec(args);
-    if (spec != NULL) {
-      return spec->GetAction().Perform(args);
-    }
-    const string message = call_description +
-        "\n    The mock function has no default action "
-        "set, and its return type has no default value set.";
-#if GTEST_HAS_EXCEPTIONS
-    if (!DefaultValue<Result>::Exists()) {
-      throw std::runtime_error(message);
-    }
-#else
-    Assert(DefaultValue<Result>::Exists(), "", -1, message);
-#endif
-    return DefaultValue<Result>::Get();
-  }
-
-  // Performs the default action with the given arguments and returns
-  // the action's result.  The call description string will be used in
-  // the error message to describe the call in the case the default
-  // action fails.  The caller is responsible for deleting the result.
-  // L = *
-  virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
-      const void* untyped_args,  // must point to an ArgumentTuple
-      const string& call_description) const {
-    const ArgumentTuple& args =
-        *static_cast<const ArgumentTuple*>(untyped_args);
-    return ResultHolder::PerformDefaultAction(this, args, call_description);
-  }
-
-  // Performs the given action with the given arguments and returns
-  // the action's result.  The caller is responsible for deleting the
-  // result.
-  // L = *
-  virtual UntypedActionResultHolderBase* UntypedPerformAction(
-      const void* untyped_action, const void* untyped_args) const {
-    // Make a copy of the action before performing it, in case the
-    // action deletes the mock object (and thus deletes itself).
-    const Action<F> action = *static_cast<const Action<F>*>(untyped_action);
-    const ArgumentTuple& args =
-        *static_cast<const ArgumentTuple*>(untyped_args);
-    return ResultHolder::PerformAction(action, args);
-  }
-
-  // Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked():
-  // clears the ON_CALL()s set on this mock function.
-  virtual void ClearDefaultActionsLocked()
-      GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-
-    // Deleting our default actions may trigger other mock objects to be
-    // deleted, for example if an action contains a reference counted smart
-    // pointer to that mock object, and that is the last reference. So if we
-    // delete our actions within the context of the global mutex we may deadlock
-    // when this method is called again. Instead, make a copy of the set of
-    // actions to delete, clear our set within the mutex, and then delete the
-    // actions outside of the mutex.
-    UntypedOnCallSpecs specs_to_delete;
-    untyped_on_call_specs_.swap(specs_to_delete);
-
-    g_gmock_mutex.Unlock();
-    for (UntypedOnCallSpecs::const_iterator it =
-             specs_to_delete.begin();
-         it != specs_to_delete.end(); ++it) {
-      delete static_cast<const OnCallSpec<F>*>(*it);
-    }
-
-    // Lock the mutex again, since the caller expects it to be locked when we
-    // return.
-    g_gmock_mutex.Lock();
-  }
-
- protected:
-  template <typename Function>
-  friend class MockSpec;
-
-  typedef ActionResultHolder<Result> ResultHolder;
-
-  // Returns the result of invoking this mock function with the given
-  // arguments.  This function can be safely called from multiple
-  // threads concurrently.
-  Result InvokeWith(const ArgumentTuple& args)
-        GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
-    scoped_ptr<ResultHolder> holder(
-        DownCast_<ResultHolder*>(this->UntypedInvokeWith(&args)));
-    return holder->Unwrap();
-  }
-
-  // Adds and returns a default action spec for this mock function.
-  OnCallSpec<F>& AddNewOnCallSpec(
-      const char* file, int line,
-      const ArgumentMatcherTuple& m)
-          GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
-    Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
-    OnCallSpec<F>* const on_call_spec = new OnCallSpec<F>(file, line, m);
-    untyped_on_call_specs_.push_back(on_call_spec);
-    return *on_call_spec;
-  }
-
-  // Adds and returns an expectation spec for this mock function.
-  TypedExpectation<F>& AddNewExpectation(
-      const char* file,
-      int line,
-      const string& source_text,
-      const ArgumentMatcherTuple& m)
-          GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
-    Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
-    TypedExpectation<F>* const expectation =
-        new TypedExpectation<F>(this, file, line, source_text, m);
-    const linked_ptr<ExpectationBase> untyped_expectation(expectation);
-    untyped_expectations_.push_back(untyped_expectation);
-
-    // Adds this expectation into the implicit sequence if there is one.
-    Sequence* const implicit_sequence = g_gmock_implicit_sequence.get();
-    if (implicit_sequence != NULL) {
-      implicit_sequence->AddExpectation(Expectation(untyped_expectation));
-    }
-
-    return *expectation;
-  }
-
-  // The current spec (either default action spec or expectation spec)
-  // being described on this function mocker.
-  MockSpec<F>& current_spec() { return current_spec_; }
-
- private:
-  template <typename Func> friend class TypedExpectation;
-
-  // Some utilities needed for implementing UntypedInvokeWith().
-
-  // Describes what default action will be performed for the given
-  // arguments.
-  // L = *
-  void DescribeDefaultActionTo(const ArgumentTuple& args,
-                               ::std::ostream* os) const {
-    const OnCallSpec<F>* const spec = FindOnCallSpec(args);
-
-    if (spec == NULL) {
-      *os << (internal::type_equals<Result, void>::value ?
-              "returning directly.\n" :
-              "returning default value.\n");
-    } else {
-      *os << "taking default action specified at:\n"
-          << FormatFileLocation(spec->file(), spec->line()) << "\n";
-    }
-  }
-
-  // Writes a message that the call is uninteresting (i.e. neither
-  // explicitly expected nor explicitly unexpected) to the given
-  // ostream.
-  virtual void UntypedDescribeUninterestingCall(
-      const void* untyped_args,
-      ::std::ostream* os) const
-          GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
-    const ArgumentTuple& args =
-        *static_cast<const ArgumentTuple*>(untyped_args);
-    *os << "Uninteresting mock function call - ";
-    DescribeDefaultActionTo(args, os);
-    *os << "    Function call: " << Name();
-    UniversalPrint(args, os);
-  }
-
-  // Returns the expectation that matches the given function arguments
-  // (or NULL is there's no match); when a match is found,
-  // untyped_action is set to point to the action that should be
-  // performed (or NULL if the action is "do default"), and
-  // is_excessive is modified to indicate whether the call exceeds the
-  // expected number.
-  //
-  // Critical section: We must find the matching expectation and the
-  // corresponding action that needs to be taken in an ATOMIC
-  // transaction.  Otherwise another thread may call this mock
-  // method in the middle and mess up the state.
-  //
-  // However, performing the action has to be left out of the critical
-  // section.  The reason is that we have no control on what the
-  // action does (it can invoke an arbitrary user function or even a
-  // mock function) and excessive locking could cause a dead lock.
-  virtual const ExpectationBase* UntypedFindMatchingExpectation(
-      const void* untyped_args,
-      const void** untyped_action, bool* is_excessive,
-      ::std::ostream* what, ::std::ostream* why)
-          GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
-    const ArgumentTuple& args =
-        *static_cast<const ArgumentTuple*>(untyped_args);
-    MutexLock l(&g_gmock_mutex);
-    TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
-    if (exp == NULL) {  // A match wasn't found.
-      this->FormatUnexpectedCallMessageLocked(args, what, why);
-      return NULL;
-    }
-
-    // This line must be done before calling GetActionForArguments(),
-    // which will increment the call count for *exp and thus affect
-    // its saturation status.
-    *is_excessive = exp->IsSaturated();
-    const Action<F>* action = exp->GetActionForArguments(this, args, what, why);
-    if (action != NULL && action->IsDoDefault())
-      action = NULL;  // Normalize "do default" to NULL.
-    *untyped_action = action;
-    return exp;
-  }
-
-  // Prints the given function arguments to the ostream.
-  virtual void UntypedPrintArgs(const void* untyped_args,
-                                ::std::ostream* os) const {
-    const ArgumentTuple& args =
-        *static_cast<const ArgumentTuple*>(untyped_args);
-    UniversalPrint(args, os);
-  }
-
-  // Returns the expectation that matches the arguments, or NULL if no
-  // expectation matches them.
-  TypedExpectation<F>* FindMatchingExpectationLocked(
-      const ArgumentTuple& args) const
-          GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-    for (typename UntypedExpectations::const_reverse_iterator it =
-             untyped_expectations_.rbegin();
-         it != untyped_expectations_.rend(); ++it) {
-      TypedExpectation<F>* const exp =
-          static_cast<TypedExpectation<F>*>(it->get());
-      if (exp->ShouldHandleArguments(args)) {
-        return exp;
-      }
-    }
-    return NULL;
-  }
-
-  // Returns a message that the arguments don't match any expectation.
-  void FormatUnexpectedCallMessageLocked(
-      const ArgumentTuple& args,
-      ::std::ostream* os,
-      ::std::ostream* why) const
-          GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-    *os << "\nUnexpected mock function call - ";
-    DescribeDefaultActionTo(args, os);
-    PrintTriedExpectationsLocked(args, why);
-  }
-
-  // Prints a list of expectations that have been tried against the
-  // current mock function call.
-  void PrintTriedExpectationsLocked(
-      const ArgumentTuple& args,
-      ::std::ostream* why) const
-          GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
-    g_gmock_mutex.AssertHeld();
-    const int count = static_cast<int>(untyped_expectations_.size());
-    *why << "Google Mock tried the following " << count << " "
-         << (count == 1 ? "expectation, but it didn't match" :
-             "expectations, but none matched")
-         << ":\n";
-    for (int i = 0; i < count; i++) {
-      TypedExpectation<F>* const expectation =
-          static_cast<TypedExpectation<F>*>(untyped_expectations_[i].get());
-      *why << "\n";
-      expectation->DescribeLocationTo(why);
-      if (count > 1) {
-        *why << "tried expectation #" << i << ": ";
-      }
-      *why << expectation->source_text() << "...\n";
-      expectation->ExplainMatchResultTo(args, why);
-      expectation->DescribeCallCountTo(why);
-    }
-  }
-
-  // The current spec (either default action spec or expectation spec)
-  // being described on this function mocker.
-  MockSpec<F> current_spec_;
-
-  // There is no generally useful and implementable semantics of
-  // copying a mock object, so copying a mock is usually a user error.
-  // Thus we disallow copying function mockers.  If the user really
-  // wants to copy a mock object, he should implement his own copy
-  // operation, for example:
-  //
-  //   class MockFoo : public Foo {
-  //    public:
-  //     // Defines a copy constructor explicitly.
-  //     MockFoo(const MockFoo& src) {}
-  //     ...
-  //   };
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(FunctionMockerBase);
-};  // class FunctionMockerBase
-
-#ifdef _MSC_VER
-# pragma warning(pop)  // Restores the warning state.
-#endif  // _MSV_VER
-
-// Implements methods of FunctionMockerBase.
-
-// Verifies that all expectations on this mock function have been
-// satisfied.  Reports one or more Google Test non-fatal failures and
-// returns false if not.
-
-// Reports an uninteresting call (whose description is in msg) in the
-// manner specified by 'reaction'.
-void ReportUninterestingCall(CallReaction reaction, const string& msg);
-
-}  // namespace internal
-
-// The style guide prohibits "using" statements in a namespace scope
-// inside a header file.  However, the MockSpec class template is
-// meant to be defined in the ::testing namespace.  The following line
-// is just a trick for working around a bug in MSVC 8.0, which cannot
-// handle it if we define MockSpec in ::testing.
-using internal::MockSpec;
-
-// Const(x) is a convenient function for obtaining a const reference
-// to x.  This is useful for setting expectations on an overloaded
-// const mock method, e.g.
-//
-//   class MockFoo : public FooInterface {
-//    public:
-//     MOCK_METHOD0(Bar, int());
-//     MOCK_CONST_METHOD0(Bar, int&());
-//   };
-//
-//   MockFoo foo;
-//   // Expects a call to non-const MockFoo::Bar().
-//   EXPECT_CALL(foo, Bar());
-//   // Expects a call to const MockFoo::Bar().
-//   EXPECT_CALL(Const(foo), Bar());
-template <typename T>
-inline const T& Const(const T& x) { return x; }
-
-// Constructs an Expectation object that references and co-owns exp.
-inline Expectation::Expectation(internal::ExpectationBase& exp)  // NOLINT
-    : expectation_base_(exp.GetHandle().expectation_base()) {}
-
-}  // namespace testing
-
-// A separate macro is required to avoid compile errors when the name
-// of the method used in call is a result of macro expansion.
-// See CompilesWithMethodNameExpandedFromMacro tests in
-// internal/gmock-spec-builders_test.cc for more details.
-#define GMOCK_ON_CALL_IMPL_(obj, call) \
-    ((obj).gmock_##call).InternalDefaultActionSetAt(__FILE__, __LINE__, \
-                                                    #obj, #call)
-#define ON_CALL(obj, call) GMOCK_ON_CALL_IMPL_(obj, call)
-
-#define GMOCK_EXPECT_CALL_IMPL_(obj, call) \
-    ((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call)
-#define EXPECT_CALL(obj, call) GMOCK_EXPECT_CALL_IMPL_(obj, call)
-
-#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
-
-#if GTEST_HAS_STD_FUNCTION_
-# include <functional>
-#endif
-
-namespace testing {
-namespace internal {
-
-template <typename F>
-class FunctionMockerBase;
-
-// Note: class FunctionMocker really belongs to the ::testing
-// namespace.  However if we define it in ::testing, MSVC will
-// complain when classes in ::testing::internal declare it as a
-// friend class template.  To workaround this compiler bug, we define
-// FunctionMocker in ::testing::internal and import it into ::testing.
-template <typename F>
-class FunctionMocker;
-
-template <typename R>
-class FunctionMocker<R()> : public
-    internal::FunctionMockerBase<R()> {
- public:
-  typedef R F();
-  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
-  MockSpec<F>& With() {
-    return this->current_spec();
-  }
-
-  R Invoke() {
-    // Even though gcc and MSVC don't enforce it, 'this->' is required
-    // by the C++ standard [14.6.4] here, as the base class type is
-    // dependent on the template argument (and thus shouldn't be
-    // looked into when resolving InvokeWith).
-    return this->InvokeWith(ArgumentTuple());
-  }
-};
-
-template <typename R, typename A1>
-class FunctionMocker<R(A1)> : public
-    internal::FunctionMockerBase<R(A1)> {
- public:
-  typedef R F(A1);
-  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
-  MockSpec<F>& With(const Matcher<A1>& m1) {
-    this->current_spec().SetMatchers(::testing::make_tuple(m1));
-    return this->current_spec();
-  }
-
-  R Invoke(A1 a1) {
-    // Even though gcc and MSVC don't enforce it, 'this->' is required
-    // by the C++ standard [14.6.4] here, as the base class type is
-    // dependent on the template argument (and thus shouldn't be
-    // looked into when resolving InvokeWith).
-    return this->InvokeWith(ArgumentTuple(a1));
-  }
-};
-
-template <typename R, typename A1, typename A2>
-class FunctionMocker<R(A1, A2)> : public
-    internal::FunctionMockerBase<R(A1, A2)> {
- public:
-  typedef R F(A1, A2);
-  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
-  MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2) {
-    this->current_spec().SetMatchers(::testing::make_tuple(m1, m2));
-    return this->current_spec();
-  }
-
-  R Invoke(A1 a1, A2 a2) {
-    // Even though gcc and MSVC don't enforce it, 'this->' is required
-    // by the C++ standard [14.6.4] here, as the base class type is
-    // dependent on the template argument (and thus shouldn't be
-    // looked into when resolving InvokeWith).
-    return this->InvokeWith(ArgumentTuple(a1, a2));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3>
-class FunctionMocker<R(A1, A2, A3)> : public
-    internal::FunctionMockerBase<R(A1, A2, A3)> {
- public:
-  typedef R F(A1, A2, A3);
-  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
-  MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
-      const Matcher<A3>& m3) {
-    this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3));
-    return this->current_spec();
-  }
-
-  R Invoke(A1 a1, A2 a2, A3 a3) {
-    // Even though gcc and MSVC don't enforce it, 'this->' is required
-    // by the C++ standard [14.6.4] here, as the base class type is
-    // dependent on the template argument (and thus shouldn't be
-    // looked into when resolving InvokeWith).
-    return this->InvokeWith(ArgumentTuple(a1, a2, a3));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4>
-class FunctionMocker<R(A1, A2, A3, A4)> : public
-    internal::FunctionMockerBase<R(A1, A2, A3, A4)> {
- public:
-  typedef R F(A1, A2, A3, A4);
-  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
-  MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
-      const Matcher<A3>& m3, const Matcher<A4>& m4) {
-    this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4));
-    return this->current_spec();
-  }
-
-  R Invoke(A1 a1, A2 a2, A3 a3, A4 a4) {
-    // Even though gcc and MSVC don't enforce it, 'this->' is required
-    // by the C++ standard [14.6.4] here, as the base class type is
-    // dependent on the template argument (and thus shouldn't be
-    // looked into when resolving InvokeWith).
-    return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5>
-class FunctionMocker<R(A1, A2, A3, A4, A5)> : public
-    internal::FunctionMockerBase<R(A1, A2, A3, A4, A5)> {
- public:
-  typedef R F(A1, A2, A3, A4, A5);
-  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
-  MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
-      const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5) {
-    this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5));
-    return this->current_spec();
-  }
-
-  R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
-    // Even though gcc and MSVC don't enforce it, 'this->' is required
-    // by the C++ standard [14.6.4] here, as the base class type is
-    // dependent on the template argument (and thus shouldn't be
-    // looked into when resolving InvokeWith).
-    return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6>
-class FunctionMocker<R(A1, A2, A3, A4, A5, A6)> : public
-    internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6)> {
- public:
-  typedef R F(A1, A2, A3, A4, A5, A6);
-  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
-  MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
-      const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
-      const Matcher<A6>& m6) {
-    this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5,
-        m6));
-    return this->current_spec();
-  }
-
-  R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
-    // Even though gcc and MSVC don't enforce it, 'this->' is required
-    // by the C++ standard [14.6.4] here, as the base class type is
-    // dependent on the template argument (and thus shouldn't be
-    // looked into when resolving InvokeWith).
-    return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6, typename A7>
-class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7)> : public
-    internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7)> {
- public:
-  typedef R F(A1, A2, A3, A4, A5, A6, A7);
-  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
-  MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
-      const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
-      const Matcher<A6>& m6, const Matcher<A7>& m7) {
-    this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5,
-        m6, m7));
-    return this->current_spec();
-  }
-
-  R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
-    // Even though gcc and MSVC don't enforce it, 'this->' is required
-    // by the C++ standard [14.6.4] here, as the base class type is
-    // dependent on the template argument (and thus shouldn't be
-    // looked into when resolving InvokeWith).
-    return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6, typename A7, typename A8>
-class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8)> : public
-    internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
- public:
-  typedef R F(A1, A2, A3, A4, A5, A6, A7, A8);
-  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
-  MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
-      const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
-      const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8) {
-    this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5,
-        m6, m7, m8));
-    return this->current_spec();
-  }
-
-  R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
-    // Even though gcc and MSVC don't enforce it, 'this->' is required
-    // by the C++ standard [14.6.4] here, as the base class type is
-    // dependent on the template argument (and thus shouldn't be
-    // looked into when resolving InvokeWith).
-    return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6, typename A7, typename A8, typename A9>
-class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> : public
-    internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
- public:
-  typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9);
-  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
-  MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
-      const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
-      const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
-      const Matcher<A9>& m9) {
-    this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5,
-        m6, m7, m8, m9));
-    return this->current_spec();
-  }
-
-  R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
-    // Even though gcc and MSVC don't enforce it, 'this->' is required
-    // by the C++ standard [14.6.4] here, as the base class type is
-    // dependent on the template argument (and thus shouldn't be
-    // looked into when resolving InvokeWith).
-    return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9));
-  }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
-    typename A5, typename A6, typename A7, typename A8, typename A9,
-    typename A10>
-class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public
-    internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> {
- public:
-  typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
-  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
-  MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
-      const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
-      const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
-      const Matcher<A9>& m9, const Matcher<A10>& m10) {
-    this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5,
-        m6, m7, m8, m9, m10));
-    return this->current_spec();
-  }
-
-  R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
-      A10 a10) {
-    // Even though gcc and MSVC don't enforce it, 'this->' is required
-    // by the C++ standard [14.6.4] here, as the base class type is
-    // dependent on the template argument (and thus shouldn't be
-    // looked into when resolving InvokeWith).
-    return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9,
-        a10));
-  }
-};
-
-}  // namespace internal
-
-// The style guide prohibits "using" statements in a namespace scope
-// inside a header file.  However, the FunctionMocker class template
-// is meant to be defined in the ::testing namespace.  The following
-// line is just a trick for working around a bug in MSVC 8.0, which
-// cannot handle it if we define FunctionMocker in ::testing.
-using internal::FunctionMocker;
-
-// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
-// We define this as a variadic macro in case F contains unprotected
-// commas (the same reason that we use variadic macros in other places
-// in this file).
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_RESULT_(tn, ...) \
-    tn ::testing::internal::Function<__VA_ARGS__>::Result
-
-// The type of argument N of the given function type.
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_ARG_(tn, N, ...) \
-    tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
-
-// The matcher type for argument N of the given function type.
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_MATCHER_(tn, N, ...) \
-    const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
-
-// The variable for mocking the given method.
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_MOCKER_(arity, constness, Method) \
-    GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
-
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \
-  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
-      ) constness { \
-    GTEST_COMPILE_ASSERT_((::testing::tuple_size<                          \
-        tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
-            == 0), \
-        this_method_does_not_take_0_arguments); \
-    GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \
-    return GMOCK_MOCKER_(0, constness, Method).Invoke(); \
-  } \
-  ::testing::MockSpec<__VA_ARGS__>& \
-      gmock_##Method() constness { \
-    GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \
-    return GMOCK_MOCKER_(0, constness, Method).With(); \
-  } \
-  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \
-      Method)
-
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \
-  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
-      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
-    GTEST_COMPILE_ASSERT_((::testing::tuple_size<                          \
-        tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
-            == 1), \
-        this_method_does_not_take_1_argument); \
-    GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \
-    return GMOCK_MOCKER_(1, constness, Method).Invoke(gmock_a1); \
-  } \
-  ::testing::MockSpec<__VA_ARGS__>& \
-      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
-    GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \
-    return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \
-  } \
-  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \
-      Method)
-
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \
-  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
-      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
-      GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
-    GTEST_COMPILE_ASSERT_((::testing::tuple_size<                          \
-        tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
-            == 2), \
-        this_method_does_not_take_2_arguments); \
-    GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \
-    return GMOCK_MOCKER_(2, constness, Method).Invoke(gmock_a1, gmock_a2); \
-  } \
-  ::testing::MockSpec<__VA_ARGS__>& \
-      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
-                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
-    GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \
-    return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \
-  } \
-  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \
-      Method)
-
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \
-  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
-      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
-      GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
-      GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
-    GTEST_COMPILE_ASSERT_((::testing::tuple_size<                          \
-        tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
-            == 3), \
-        this_method_does_not_take_3_arguments); \
-    GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \
-    return GMOCK_MOCKER_(3, constness, Method).Invoke(gmock_a1, gmock_a2, \
-        gmock_a3); \
-  } \
-  ::testing::MockSpec<__VA_ARGS__>& \
-      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
-                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
-                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
-    GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \
-    return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \
-        gmock_a3); \
-  } \
-  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \
-      Method)
-
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \
-  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
-      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
-      GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
-      GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
-      GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
-    GTEST_COMPILE_ASSERT_((::testing::tuple_size<                          \
-        tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
-            == 4), \
-        this_method_does_not_take_4_arguments); \
-    GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \
-    return GMOCK_MOCKER_(4, constness, Method).Invoke(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4); \
-  } \
-  ::testing::MockSpec<__VA_ARGS__>& \
-      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
-                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
-                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
-                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
-    GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \
-    return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4); \
-  } \
-  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \
-      Method)
-
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \
-  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
-      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
-      GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
-      GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
-      GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
-      GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5) constness { \
-    GTEST_COMPILE_ASSERT_((::testing::tuple_size<                          \
-        tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
-            == 5), \
-        this_method_does_not_take_5_arguments); \
-    GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \
-    return GMOCK_MOCKER_(5, constness, Method).Invoke(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4, gmock_a5); \
-  } \
-  ::testing::MockSpec<__VA_ARGS__>& \
-      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
-                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
-                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
-                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
-                     GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5) constness { \
-    GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \
-    return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4, gmock_a5); \
-  } \
-  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \
-      Method)
-
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \
-  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
-      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
-      GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
-      GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
-      GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
-      GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
-      GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6) constness { \
-    GTEST_COMPILE_ASSERT_((::testing::tuple_size<                          \
-        tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
-            == 6), \
-        this_method_does_not_take_6_arguments); \
-    GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \
-    return GMOCK_MOCKER_(6, constness, Method).Invoke(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
-  } \
-  ::testing::MockSpec<__VA_ARGS__>& \
-      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
-                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
-                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
-                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
-                     GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
-                     GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6) constness { \
-    GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \
-    return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
-  } \
-  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \
-      Method)
-
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \
-  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
-      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
-      GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
-      GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
-      GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
-      GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
-      GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
-      GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
-    GTEST_COMPILE_ASSERT_((::testing::tuple_size<                          \
-        tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
-            == 7), \
-        this_method_does_not_take_7_arguments); \
-    GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \
-    return GMOCK_MOCKER_(7, constness, Method).Invoke(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
-  } \
-  ::testing::MockSpec<__VA_ARGS__>& \
-      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
-                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
-                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
-                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
-                     GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
-                     GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
-                     GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
-    GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \
-    return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
-  } \
-  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \
-      Method)
-
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \
-  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
-      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
-      GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
-      GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
-      GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
-      GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
-      GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
-      GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
-      GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8) constness { \
-    GTEST_COMPILE_ASSERT_((::testing::tuple_size<                          \
-        tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
-            == 8), \
-        this_method_does_not_take_8_arguments); \
-    GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \
-    return GMOCK_MOCKER_(8, constness, Method).Invoke(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
-  } \
-  ::testing::MockSpec<__VA_ARGS__>& \
-      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
-                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
-                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
-                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
-                     GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
-                     GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
-                     GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
-                     GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8) constness { \
-    GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \
-    return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
-  } \
-  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \
-      Method)
-
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \
-  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
-      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
-      GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
-      GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
-      GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
-      GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
-      GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
-      GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
-      GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \
-      GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9) constness { \
-    GTEST_COMPILE_ASSERT_((::testing::tuple_size<                          \
-        tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
-            == 9), \
-        this_method_does_not_take_9_arguments); \
-    GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \
-    return GMOCK_MOCKER_(9, constness, Method).Invoke(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
-        gmock_a9); \
-  } \
-  ::testing::MockSpec<__VA_ARGS__>& \
-      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
-                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
-                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
-                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
-                     GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
-                     GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
-                     GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
-                     GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
-                     GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9) constness { \
-    GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \
-    return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
-        gmock_a9); \
-  } \
-  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \
-      Method)
-
-// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
-#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \
-  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
-      GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
-      GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
-      GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
-      GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
-      GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
-      GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
-      GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
-      GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \
-      GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \
-      GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \
-    GTEST_COMPILE_ASSERT_((::testing::tuple_size<                          \
-        tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
-            == 10), \
-        this_method_does_not_take_10_arguments); \
-    GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \
-    return GMOCK_MOCKER_(10, constness, Method).Invoke(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
-        gmock_a10); \
-  } \
-  ::testing::MockSpec<__VA_ARGS__>& \
-      gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
-                     GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
-                     GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
-                     GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \
-                     GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \
-                     GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \
-                     GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \
-                     GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \
-                     GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9, \
-                     GMOCK_MATCHER_(tn, 10, \
-                         __VA_ARGS__) gmock_a10) constness { \
-    GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \
-    return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \
-        gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
-        gmock_a10); \
-  } \
-  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \
-      Method)
-
-#define MOCK_METHOD0(m, ...) GMOCK_METHOD0_(, , , m, __VA_ARGS__)
-#define MOCK_METHOD1(m, ...) GMOCK_METHOD1_(, , , m, __VA_ARGS__)
-#define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__)
-#define MOCK_METHOD3(m, ...) GMOCK_METHOD3_(, , , m, __VA_ARGS__)
-#define MOCK_METHOD4(m, ...) GMOCK_METHOD4_(, , , m, __VA_ARGS__)
-#define MOCK_METHOD5(m, ...) GMOCK_METHOD5_(, , , m, __VA_ARGS__)
-#define MOCK_METHOD6(m, ...) GMOCK_METHOD6_(, , , m, __VA_ARGS__)
-#define MOCK_METHOD7(m, ...) GMOCK_METHOD7_(, , , m, __VA_ARGS__)
-#define MOCK_METHOD8(m, ...) GMOCK_METHOD8_(, , , m, __VA_ARGS__)
-#define MOCK_METHOD9(m, ...) GMOCK_METHOD9_(, , , m, __VA_ARGS__)
-#define MOCK_METHOD10(m, ...) GMOCK_METHOD10_(, , , m, __VA_ARGS__)
-
-#define MOCK_CONST_METHOD0(m, ...) GMOCK_METHOD0_(, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD1(m, ...) GMOCK_METHOD1_(, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD3(m, ...) GMOCK_METHOD3_(, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD4(m, ...) GMOCK_METHOD4_(, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD5(m, ...) GMOCK_METHOD5_(, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD6(m, ...) GMOCK_METHOD6_(, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD7(m, ...) GMOCK_METHOD7_(, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD8(m, ...) GMOCK_METHOD8_(, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD9(m, ...) GMOCK_METHOD9_(, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD10(m, ...) GMOCK_METHOD10_(, const, , m, __VA_ARGS__)
-
-#define MOCK_METHOD0_T(m, ...) GMOCK_METHOD0_(typename, , , m, __VA_ARGS__)
-#define MOCK_METHOD1_T(m, ...) GMOCK_METHOD1_(typename, , , m, __VA_ARGS__)
-#define MOCK_METHOD2_T(m, ...) GMOCK_METHOD2_(typename, , , m, __VA_ARGS__)
-#define MOCK_METHOD3_T(m, ...) GMOCK_METHOD3_(typename, , , m, __VA_ARGS__)
-#define MOCK_METHOD4_T(m, ...) GMOCK_METHOD4_(typename, , , m, __VA_ARGS__)
-#define MOCK_METHOD5_T(m, ...) GMOCK_METHOD5_(typename, , , m, __VA_ARGS__)
-#define MOCK_METHOD6_T(m, ...) GMOCK_METHOD6_(typename, , , m, __VA_ARGS__)
-#define MOCK_METHOD7_T(m, ...) GMOCK_METHOD7_(typename, , , m, __VA_ARGS__)
-#define MOCK_METHOD8_T(m, ...) GMOCK_METHOD8_(typename, , , m, __VA_ARGS__)
-#define MOCK_METHOD9_T(m, ...) GMOCK_METHOD9_(typename, , , m, __VA_ARGS__)
-#define MOCK_METHOD10_T(m, ...) GMOCK_METHOD10_(typename, , , m, __VA_ARGS__)
-
-#define MOCK_CONST_METHOD0_T(m, ...) \
-    GMOCK_METHOD0_(typename, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD1_T(m, ...) \
-    GMOCK_METHOD1_(typename, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD2_T(m, ...) \
-    GMOCK_METHOD2_(typename, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD3_T(m, ...) \
-    GMOCK_METHOD3_(typename, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD4_T(m, ...) \
-    GMOCK_METHOD4_(typename, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD5_T(m, ...) \
-    GMOCK_METHOD5_(typename, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD6_T(m, ...) \
-    GMOCK_METHOD6_(typename, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD7_T(m, ...) \
-    GMOCK_METHOD7_(typename, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD8_T(m, ...) \
-    GMOCK_METHOD8_(typename, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD9_T(m, ...) \
-    GMOCK_METHOD9_(typename, const, , m, __VA_ARGS__)
-#define MOCK_CONST_METHOD10_T(m, ...) \
-    GMOCK_METHOD10_(typename, const, , m, __VA_ARGS__)
-
-#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD0_(, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD1_(, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD2_(, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD3_(, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD4_(, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD5_(, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD6_(, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD7_(, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD8_(, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD9_(, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD10_(, , ct, m, __VA_ARGS__)
-
-#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD0_(, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD1_(, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD2_(, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD3_(, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD4_(, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD5_(, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD6_(, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD7_(, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD8_(, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD9_(, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD10_(, const, ct, m, __VA_ARGS__)
-
-#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD0_(typename, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD1_(typename, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD2_(typename, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD3_(typename, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD4_(typename, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD5_(typename, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD6_(typename, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD7_(typename, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD8_(typename, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD9_(typename, , ct, m, __VA_ARGS__)
-#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD10_(typename, , ct, m, __VA_ARGS__)
-
-#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD0_(typename, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD1_(typename, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD2_(typename, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD3_(typename, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD4_(typename, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD5_(typename, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD6_(typename, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD7_(typename, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD8_(typename, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD9_(typename, const, ct, m, __VA_ARGS__)
-#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
-    GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__)
-
-// A MockFunction<F> class has one mock method whose type is F.  It is
-// useful when you just want your test code to emit some messages and
-// have Google Mock verify the right messages are sent (and perhaps at
-// the right times).  For example, if you are exercising code:
-//
-//   Foo(1);
-//   Foo(2);
-//   Foo(3);
-//
-// and want to verify that Foo(1) and Foo(3) both invoke
-// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
-//
-// TEST(FooTest, InvokesBarCorrectly) {
-//   MyMock mock;
-//   MockFunction<void(string check_point_name)> check;
-//   {
-//     InSequence s;
-//
-//     EXPECT_CALL(mock, Bar("a"));
-//     EXPECT_CALL(check, Call("1"));
-//     EXPECT_CALL(check, Call("2"));
-//     EXPECT_CALL(mock, Bar("a"));
-//   }
-//   Foo(1);
-//   check.Call("1");
-//   Foo(2);
-//   check.Call("2");
-//   Foo(3);
-// }
-//
-// The expectation spec says that the first Bar("a") must happen
-// before check point "1", the second Bar("a") must happen after check
-// point "2", and nothing should happen between the two check
-// points. The explicit check points make it easy to tell which
-// Bar("a") is called by which call to Foo().
-//
-// MockFunction<F> can also be used to exercise code that accepts
-// std::function<F> callbacks. To do so, use AsStdFunction() method
-// to create std::function proxy forwarding to original object's Call.
-// Example:
-//
-// TEST(FooTest, RunsCallbackWithBarArgument) {
-//   MockFunction<int(string)> callback;
-//   EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
-//   Foo(callback.AsStdFunction());
-// }
-template <typename F>
-class MockFunction;
-
-template <typename R>
-class MockFunction<R()> {
- public:
-  MockFunction() {}
-
-  MOCK_METHOD0_T(Call, R());
-
-#if GTEST_HAS_STD_FUNCTION_
-  std::function<R()> AsStdFunction() {
-    return [this]() -> R {
-      return this->Call();
-    };
-  }
-#endif  // GTEST_HAS_STD_FUNCTION_
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0>
-class MockFunction<R(A0)> {
- public:
-  MockFunction() {}
-
-  MOCK_METHOD1_T(Call, R(A0));
-
-#if GTEST_HAS_STD_FUNCTION_
-  std::function<R(A0)> AsStdFunction() {
-    return [this](A0 a0) -> R {
-      return this->Call(a0);
-    };
-  }
-#endif  // GTEST_HAS_STD_FUNCTION_
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1>
-class MockFunction<R(A0, A1)> {
- public:
-  MockFunction() {}
-
-  MOCK_METHOD2_T(Call, R(A0, A1));
-
-#if GTEST_HAS_STD_FUNCTION_
-  std::function<R(A0, A1)> AsStdFunction() {
-    return [this](A0 a0, A1 a1) -> R {
-      return this->Call(a0, a1);
-    };
-  }
-#endif  // GTEST_HAS_STD_FUNCTION_
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2>
-class MockFunction<R(A0, A1, A2)> {
- public:
-  MockFunction() {}
-
-  MOCK_METHOD3_T(Call, R(A0, A1, A2));
-
-#if GTEST_HAS_STD_FUNCTION_
-  std::function<R(A0, A1, A2)> AsStdFunction() {
-    return [this](A0 a0, A1 a1, A2 a2) -> R {
-      return this->Call(a0, a1, a2);
-    };
-  }
-#endif  // GTEST_HAS_STD_FUNCTION_
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3>
-class MockFunction<R(A0, A1, A2, A3)> {
- public:
-  MockFunction() {}
-
-  MOCK_METHOD4_T(Call, R(A0, A1, A2, A3));
-
-#if GTEST_HAS_STD_FUNCTION_
-  std::function<R(A0, A1, A2, A3)> AsStdFunction() {
-    return [this](A0 a0, A1 a1, A2 a2, A3 a3) -> R {
-      return this->Call(a0, a1, a2, a3);
-    };
-  }
-#endif  // GTEST_HAS_STD_FUNCTION_
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3,
-    typename A4>
-class MockFunction<R(A0, A1, A2, A3, A4)> {
- public:
-  MockFunction() {}
-
-  MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4));
-
-#if GTEST_HAS_STD_FUNCTION_
-  std::function<R(A0, A1, A2, A3, A4)> AsStdFunction() {
-    return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) -> R {
-      return this->Call(a0, a1, a2, a3, a4);
-    };
-  }
-#endif  // GTEST_HAS_STD_FUNCTION_
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3,
-    typename A4, typename A5>
-class MockFunction<R(A0, A1, A2, A3, A4, A5)> {
- public:
-  MockFunction() {}
-
-  MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5));
-
-#if GTEST_HAS_STD_FUNCTION_
-  std::function<R(A0, A1, A2, A3, A4, A5)> AsStdFunction() {
-    return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) -> R {
-      return this->Call(a0, a1, a2, a3, a4, a5);
-    };
-  }
-#endif  // GTEST_HAS_STD_FUNCTION_
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3,
-    typename A4, typename A5, typename A6>
-class MockFunction<R(A0, A1, A2, A3, A4, A5, A6)> {
- public:
-  MockFunction() {}
-
-  MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6));
-
-#if GTEST_HAS_STD_FUNCTION_
-  std::function<R(A0, A1, A2, A3, A4, A5, A6)> AsStdFunction() {
-    return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) -> R {
-      return this->Call(a0, a1, a2, a3, a4, a5, a6);
-    };
-  }
-#endif  // GTEST_HAS_STD_FUNCTION_
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3,
-    typename A4, typename A5, typename A6, typename A7>
-class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7)> {
- public:
-  MockFunction() {}
-
-  MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7));
-
-#if GTEST_HAS_STD_FUNCTION_
-  std::function<R(A0, A1, A2, A3, A4, A5, A6, A7)> AsStdFunction() {
-    return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) -> R {
-      return this->Call(a0, a1, a2, a3, a4, a5, a6, a7);
-    };
-  }
-#endif  // GTEST_HAS_STD_FUNCTION_
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3,
-    typename A4, typename A5, typename A6, typename A7, typename A8>
-class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> {
- public:
-  MockFunction() {}
-
-  MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8));
-
-#if GTEST_HAS_STD_FUNCTION_
-  std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> AsStdFunction() {
-    return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7,
-        A8 a8) -> R {
-      return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8);
-    };
-  }
-#endif  // GTEST_HAS_STD_FUNCTION_
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3,
-    typename A4, typename A5, typename A6, typename A7, typename A8,
-    typename A9>
-class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
- public:
-  MockFunction() {}
-
-  MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9));
-
-#if GTEST_HAS_STD_FUNCTION_
-  std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> AsStdFunction() {
-    return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7,
-        A8 a8, A9 a9) -> R {
-      return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
-    };
-  }
-#endif  // GTEST_HAS_STD_FUNCTION_
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-}  // namespace testing
-
-#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
-// This file was GENERATED by command:
-//     pump.py gmock-generated-nice-strict.h.pump
-// DO NOT EDIT BY HAND!!!
-
-// Copyright 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: wan@google.com (Zhanyong Wan)
-
-// Implements class templates NiceMock, NaggyMock, and StrictMock.
-//
-// Given a mock class MockFoo that is created using Google Mock,
-// NiceMock<MockFoo> is a subclass of MockFoo that allows
-// uninteresting calls (i.e. calls to mock methods that have no
-// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
-// that prints a warning when an uninteresting call occurs, and
-// StrictMock<MockFoo> is a subclass of MockFoo that treats all
-// uninteresting calls as errors.
-//
-// Currently a mock is naggy by default, so MockFoo and
-// NaggyMock<MockFoo> behave like the same.  However, we will soon
-// switch the default behavior of mocks to be nice, as that in general
-// leads to more maintainable tests.  When that happens, MockFoo will
-// stop behaving like NaggyMock<MockFoo> and start behaving like
-// NiceMock<MockFoo>.
-//
-// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
-// their respective base class, with up-to 10 arguments.  Therefore
-// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock
-// where MockFoo has a constructor that accepts (int, const char*),
-// for example.
-//
-// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
-// and StrictMock<MockFoo> only works for mock methods defined using
-// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
-// If a mock method is defined in a base class of MockFoo, the "nice"
-// or "strict" modifier may not affect it, depending on the compiler.
-// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
-// supported.
-//
-// Another known limitation is that the constructors of the base mock
-// cannot have arguments passed by non-const reference, which are
-// banned by the Google C++ style guide anyway.
-
-#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
-#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
-
-
-namespace testing {
-
-template <class MockClass>
-class NiceMock : public MockClass {
- public:
-  // We don't factor out the constructor body to a common method, as
-  // we have to avoid a possible clash with members of MockClass.
-  NiceMock() {
-    ::testing::Mock::AllowUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  // C++ doesn't (yet) allow inheritance of constructors, so we have
-  // to define it for each arity.
-  template <typename A1>
-  explicit NiceMock(const A1& a1) : MockClass(a1) {
-    ::testing::Mock::AllowUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-  template <typename A1, typename A2>
-  NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
-    ::testing::Mock::AllowUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3>
-  NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
-    ::testing::Mock::AllowUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4>
-  NiceMock(const A1& a1, const A2& a2, const A3& a3,
-      const A4& a4) : MockClass(a1, a2, a3, a4) {
-    ::testing::Mock::AllowUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5>
-  NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
-    ::testing::Mock::AllowUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6>
-  NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
-    ::testing::Mock::AllowUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6, typename A7>
-  NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
-      a6, a7) {
-    ::testing::Mock::AllowUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6, typename A7, typename A8>
-  NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
-      a2, a3, a4, a5, a6, a7, a8) {
-    ::testing::Mock::AllowUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6, typename A7, typename A8, typename A9>
-  NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6, const A7& a7, const A8& a8,
-      const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
-    ::testing::Mock::AllowUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6, typename A7, typename A8, typename A9, typename A10>
-  NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
-      const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
-    ::testing::Mock::AllowUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  virtual ~NiceMock() {
-    ::testing::Mock::UnregisterCallReaction(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock);
-};
-
-template <class MockClass>
-class NaggyMock : public MockClass {
- public:
-  // We don't factor out the constructor body to a common method, as
-  // we have to avoid a possible clash with members of MockClass.
-  NaggyMock() {
-    ::testing::Mock::WarnUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  // C++ doesn't (yet) allow inheritance of constructors, so we have
-  // to define it for each arity.
-  template <typename A1>
-  explicit NaggyMock(const A1& a1) : MockClass(a1) {
-    ::testing::Mock::WarnUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-  template <typename A1, typename A2>
-  NaggyMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
-    ::testing::Mock::WarnUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3>
-  NaggyMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
-    ::testing::Mock::WarnUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4>
-  NaggyMock(const A1& a1, const A2& a2, const A3& a3,
-      const A4& a4) : MockClass(a1, a2, a3, a4) {
-    ::testing::Mock::WarnUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5>
-  NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
-    ::testing::Mock::WarnUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6>
-  NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
-    ::testing::Mock::WarnUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6, typename A7>
-  NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
-      a6, a7) {
-    ::testing::Mock::WarnUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6, typename A7, typename A8>
-  NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
-      a2, a3, a4, a5, a6, a7, a8) {
-    ::testing::Mock::WarnUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6, typename A7, typename A8, typename A9>
-  NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6, const A7& a7, const A8& a8,
-      const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
-    ::testing::Mock::WarnUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6, typename A7, typename A8, typename A9, typename A10>
-  NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
-      const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
-    ::testing::Mock::WarnUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  virtual ~NaggyMock() {
-    ::testing::Mock::UnregisterCallReaction(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock);
-};
-
-template <class MockClass>
-class StrictMock : public MockClass {
- public:
-  // We don't factor out the constructor body to a common method, as
-  // we have to avoid a possible clash with members of MockClass.
-  StrictMock() {
-    ::testing::Mock::FailUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  // C++ doesn't (yet) allow inheritance of constructors, so we have
-  // to define it for each arity.
-  template <typename A1>
-  explicit StrictMock(const A1& a1) : MockClass(a1) {
-    ::testing::Mock::FailUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-  template <typename A1, typename A2>
-  StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
-    ::testing::Mock::FailUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3>
-  StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
-    ::testing::Mock::FailUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4>
-  StrictMock(const A1& a1, const A2& a2, const A3& a3,
-      const A4& a4) : MockClass(a1, a2, a3, a4) {
-    ::testing::Mock::FailUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5>
-  StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
-    ::testing::Mock::FailUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6>
-  StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
-    ::testing::Mock::FailUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6, typename A7>
-  StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
-      a6, a7) {
-    ::testing::Mock::FailUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6, typename A7, typename A8>
-  StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
-      a2, a3, a4, a5, a6, a7, a8) {
-    ::testing::Mock::FailUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6, typename A7, typename A8, typename A9>
-  StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6, const A7& a7, const A8& a8,
-      const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
-    ::testing::Mock::FailUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  template <typename A1, typename A2, typename A3, typename A4, typename A5,
-      typename A6, typename A7, typename A8, typename A9, typename A10>
-  StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
-      const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
-      const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
-    ::testing::Mock::FailUninterestingCalls(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
-  virtual ~StrictMock() {
-    ::testing::Mock::UnregisterCallReaction(
-        internal::ImplicitCast_<MockClass*>(this));
-  }
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
-};
-
-// The following specializations catch some (relatively more common)
-// user errors of nesting nice and strict mocks.  They do NOT catch
-// all possible errors.
-
-// These specializations are declared but not defined, as NiceMock,
-// NaggyMock, and StrictMock cannot be nested.
-
-template <typename MockClass>
-class NiceMock<NiceMock<MockClass> >;
-template <typename MockClass>
-class NiceMock<NaggyMock<MockClass> >;
-template <typename MockClass>
-class NiceMock<StrictMock<MockClass> >;
-
-template <typename MockClass>
-class NaggyMock<NiceMock<MockClass> >;
-template <typename MockClass>
-class NaggyMock<NaggyMock<MockClass> >;
-template <typename MockClass>
-class NaggyMock<StrictMock<MockClass> >;
-
-template <typename MockClass>
-class StrictMock<NiceMock<MockClass> >;
-template <typename MockClass>
-class StrictMock<NaggyMock<MockClass> >;
-template <typename MockClass>
-class StrictMock<StrictMock<MockClass> >;
-
-}  // namespace testing
-
-#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
-// This file was GENERATED by command:
 //     pump.py gmock-generated-matchers.h.pump
 // DO NOT EDIT BY HAND!!!
 
@@ -12506,1133 +11859,17 @@
 //
 // This file implements some commonly used variadic matchers.
 
+// GOOGLETEST_CM0002 DO NOT DELETE
+
 #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
 #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
 
 #include <iterator>
 #include <sstream>
 #include <string>
+#include <utility>
 #include <vector>
 
-namespace testing {
-namespace internal {
-
-// The type of the i-th (0-based) field of Tuple.
-#define GMOCK_FIELD_TYPE_(Tuple, i) \
-    typename ::testing::tuple_element<i, Tuple>::type
-
-// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a
-// tuple of type Tuple.  It has two members:
-//
-//   type: a tuple type whose i-th field is the ki-th field of Tuple.
-//   GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple.
-//
-// For example, in class TupleFields<tuple<bool, char, int>, 2, 0>, we have:
-//
-//   type is tuple<int, bool>, and
-//   GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true).
-
-template <class Tuple, int k0 = -1, int k1 = -1, int k2 = -1, int k3 = -1,
-    int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1,
-    int k9 = -1>
-class TupleFields;
-
-// This generic version is used when there are 10 selectors.
-template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6,
-    int k7, int k8, int k9>
-class TupleFields {
- public:
-  typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
-      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
-      GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
-      GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6),
-      GMOCK_FIELD_TYPE_(Tuple, k7), GMOCK_FIELD_TYPE_(Tuple, k8),
-      GMOCK_FIELD_TYPE_(Tuple, k9)> type;
-  static type GetSelectedFields(const Tuple& t) {
-    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
-        get<k5>(t), get<k6>(t), get<k7>(t), get<k8>(t), get<k9>(t));
-  }
-};
-
-// The following specialization is used for 0 ~ 9 selectors.
-
-template <class Tuple>
-class TupleFields<Tuple, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
- public:
-  typedef ::testing::tuple<> type;
-  static type GetSelectedFields(const Tuple& /* t */) {
-    return type();
-  }
-};
-
-template <class Tuple, int k0>
-class TupleFields<Tuple, k0, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
- public:
-  typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0)> type;
-  static type GetSelectedFields(const Tuple& t) {
-    return type(get<k0>(t));
-  }
-};
-
-template <class Tuple, int k0, int k1>
-class TupleFields<Tuple, k0, k1, -1, -1, -1, -1, -1, -1, -1, -1> {
- public:
-  typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
-      GMOCK_FIELD_TYPE_(Tuple, k1)> type;
-  static type GetSelectedFields(const Tuple& t) {
-    return type(get<k0>(t), get<k1>(t));
-  }
-};
-
-template <class Tuple, int k0, int k1, int k2>
-class TupleFields<Tuple, k0, k1, k2, -1, -1, -1, -1, -1, -1, -1> {
- public:
-  typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
-      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2)> type;
-  static type GetSelectedFields(const Tuple& t) {
-    return type(get<k0>(t), get<k1>(t), get<k2>(t));
-  }
-};
-
-template <class Tuple, int k0, int k1, int k2, int k3>
-class TupleFields<Tuple, k0, k1, k2, k3, -1, -1, -1, -1, -1, -1> {
- public:
-  typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
-      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
-      GMOCK_FIELD_TYPE_(Tuple, k3)> type;
-  static type GetSelectedFields(const Tuple& t) {
-    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t));
-  }
-};
-
-template <class Tuple, int k0, int k1, int k2, int k3, int k4>
-class TupleFields<Tuple, k0, k1, k2, k3, k4, -1, -1, -1, -1, -1> {
- public:
-  typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
-      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
-      GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4)> type;
-  static type GetSelectedFields(const Tuple& t) {
-    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t));
-  }
-};
-
-template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5>
-class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, -1, -1, -1, -1> {
- public:
-  typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
-      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
-      GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
-      GMOCK_FIELD_TYPE_(Tuple, k5)> type;
-  static type GetSelectedFields(const Tuple& t) {
-    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
-        get<k5>(t));
-  }
-};
-
-template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6>
-class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, -1, -1, -1> {
- public:
-  typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
-      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
-      GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
-      GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6)> type;
-  static type GetSelectedFields(const Tuple& t) {
-    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
-        get<k5>(t), get<k6>(t));
-  }
-};
-
-template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6,
-    int k7>
-class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, k7, -1, -1> {
- public:
-  typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
-      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
-      GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
-      GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6),
-      GMOCK_FIELD_TYPE_(Tuple, k7)> type;
-  static type GetSelectedFields(const Tuple& t) {
-    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
-        get<k5>(t), get<k6>(t), get<k7>(t));
-  }
-};
-
-template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6,
-    int k7, int k8>
-class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, k7, k8, -1> {
- public:
-  typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
-      GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
-      GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
-      GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6),
-      GMOCK_FIELD_TYPE_(Tuple, k7), GMOCK_FIELD_TYPE_(Tuple, k8)> type;
-  static type GetSelectedFields(const Tuple& t) {
-    return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
-        get<k5>(t), get<k6>(t), get<k7>(t), get<k8>(t));
-  }
-};
-
-#undef GMOCK_FIELD_TYPE_
-
-// Implements the Args() matcher.
-template <class ArgsTuple, int k0 = -1, int k1 = -1, int k2 = -1, int k3 = -1,
-    int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1,
-    int k9 = -1>
-class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
- public:
-  // ArgsTuple may have top-level const or reference modifiers.
-  typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple;
-  typedef typename internal::TupleFields<RawArgsTuple, k0, k1, k2, k3, k4, k5,
-      k6, k7, k8, k9>::type SelectedArgs;
-  typedef Matcher<const SelectedArgs&> MonomorphicInnerMatcher;
-
-  template <typename InnerMatcher>
-  explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
-      : inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
-
-  virtual bool MatchAndExplain(ArgsTuple args,
-                               MatchResultListener* listener) const {
-    const SelectedArgs& selected_args = GetSelectedArgs(args);
-    if (!listener->IsInterested())
-      return inner_matcher_.Matches(selected_args);
-
-    PrintIndices(listener->stream());
-    *listener << "are " << PrintToString(selected_args);
-
-    StringMatchResultListener inner_listener;
-    const bool match = inner_matcher_.MatchAndExplain(selected_args,
-                                                      &inner_listener);
-    PrintIfNotEmpty(inner_listener.str(), listener->stream());
-    return match;
-  }
-
-  virtual void DescribeTo(::std::ostream* os) const {
-    *os << "are a tuple ";
-    PrintIndices(os);
-    inner_matcher_.DescribeTo(os);
-  }
-
-  virtual void DescribeNegationTo(::std::ostream* os) const {
-    *os << "are a tuple ";
-    PrintIndices(os);
-    inner_matcher_.DescribeNegationTo(os);
-  }
-
- private:
-  static SelectedArgs GetSelectedArgs(ArgsTuple args) {
-    return TupleFields<RawArgsTuple, k0, k1, k2, k3, k4, k5, k6, k7, k8,
-        k9>::GetSelectedFields(args);
-  }
-
-  // Prints the indices of the selected fields.
-  static void PrintIndices(::std::ostream* os) {
-    *os << "whose fields (";
-    const int indices[10] = { k0, k1, k2, k3, k4, k5, k6, k7, k8, k9 };
-    for (int i = 0; i < 10; i++) {
-      if (indices[i] < 0)
-        break;
-
-      if (i >= 1)
-        *os << ", ";
-
-      *os << "#" << indices[i];
-    }
-    *os << ") ";
-  }
-
-  const MonomorphicInnerMatcher inner_matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl);
-};
-
-template <class InnerMatcher, int k0 = -1, int k1 = -1, int k2 = -1,
-    int k3 = -1, int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1,
-    int k8 = -1, int k9 = -1>
-class ArgsMatcher {
- public:
-  explicit ArgsMatcher(const InnerMatcher& inner_matcher)
-      : inner_matcher_(inner_matcher) {}
-
-  template <typename ArgsTuple>
-  operator Matcher<ArgsTuple>() const {
-    return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, k0, k1, k2, k3, k4, k5,
-        k6, k7, k8, k9>(inner_matcher_));
-  }
-
- private:
-  const InnerMatcher inner_matcher_;
-
-  GTEST_DISALLOW_ASSIGN_(ArgsMatcher);
-};
-
-// A set of metafunctions for computing the result type of AllOf.
-// AllOf(m1, ..., mN) returns
-// AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
-
-// Although AllOf isn't defined for one argument, AllOfResult1 is defined
-// to simplify the implementation.
-template <typename M1>
-struct AllOfResult1 {
-  typedef M1 type;
-};
-
-template <typename M1, typename M2>
-struct AllOfResult2 {
-  typedef BothOfMatcher<
-      typename AllOfResult1<M1>::type,
-      typename AllOfResult1<M2>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3>
-struct AllOfResult3 {
-  typedef BothOfMatcher<
-      typename AllOfResult1<M1>::type,
-      typename AllOfResult2<M2, M3>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4>
-struct AllOfResult4 {
-  typedef BothOfMatcher<
-      typename AllOfResult2<M1, M2>::type,
-      typename AllOfResult2<M3, M4>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5>
-struct AllOfResult5 {
-  typedef BothOfMatcher<
-      typename AllOfResult2<M1, M2>::type,
-      typename AllOfResult3<M3, M4, M5>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6>
-struct AllOfResult6 {
-  typedef BothOfMatcher<
-      typename AllOfResult3<M1, M2, M3>::type,
-      typename AllOfResult3<M4, M5, M6>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7>
-struct AllOfResult7 {
-  typedef BothOfMatcher<
-      typename AllOfResult3<M1, M2, M3>::type,
-      typename AllOfResult4<M4, M5, M6, M7>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7, typename M8>
-struct AllOfResult8 {
-  typedef BothOfMatcher<
-      typename AllOfResult4<M1, M2, M3, M4>::type,
-      typename AllOfResult4<M5, M6, M7, M8>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7, typename M8, typename M9>
-struct AllOfResult9 {
-  typedef BothOfMatcher<
-      typename AllOfResult4<M1, M2, M3, M4>::type,
-      typename AllOfResult5<M5, M6, M7, M8, M9>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7, typename M8, typename M9, typename M10>
-struct AllOfResult10 {
-  typedef BothOfMatcher<
-      typename AllOfResult5<M1, M2, M3, M4, M5>::type,
-      typename AllOfResult5<M6, M7, M8, M9, M10>::type
-  > type;
-};
-
-// A set of metafunctions for computing the result type of AnyOf.
-// AnyOf(m1, ..., mN) returns
-// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type.
-
-// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined
-// to simplify the implementation.
-template <typename M1>
-struct AnyOfResult1 {
-  typedef M1 type;
-};
-
-template <typename M1, typename M2>
-struct AnyOfResult2 {
-  typedef EitherOfMatcher<
-      typename AnyOfResult1<M1>::type,
-      typename AnyOfResult1<M2>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3>
-struct AnyOfResult3 {
-  typedef EitherOfMatcher<
-      typename AnyOfResult1<M1>::type,
-      typename AnyOfResult2<M2, M3>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4>
-struct AnyOfResult4 {
-  typedef EitherOfMatcher<
-      typename AnyOfResult2<M1, M2>::type,
-      typename AnyOfResult2<M3, M4>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5>
-struct AnyOfResult5 {
-  typedef EitherOfMatcher<
-      typename AnyOfResult2<M1, M2>::type,
-      typename AnyOfResult3<M3, M4, M5>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6>
-struct AnyOfResult6 {
-  typedef EitherOfMatcher<
-      typename AnyOfResult3<M1, M2, M3>::type,
-      typename AnyOfResult3<M4, M5, M6>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7>
-struct AnyOfResult7 {
-  typedef EitherOfMatcher<
-      typename AnyOfResult3<M1, M2, M3>::type,
-      typename AnyOfResult4<M4, M5, M6, M7>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7, typename M8>
-struct AnyOfResult8 {
-  typedef EitherOfMatcher<
-      typename AnyOfResult4<M1, M2, M3, M4>::type,
-      typename AnyOfResult4<M5, M6, M7, M8>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7, typename M8, typename M9>
-struct AnyOfResult9 {
-  typedef EitherOfMatcher<
-      typename AnyOfResult4<M1, M2, M3, M4>::type,
-      typename AnyOfResult5<M5, M6, M7, M8, M9>::type
-  > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7, typename M8, typename M9, typename M10>
-struct AnyOfResult10 {
-  typedef EitherOfMatcher<
-      typename AnyOfResult5<M1, M2, M3, M4, M5>::type,
-      typename AnyOfResult5<M6, M7, M8, M9, M10>::type
-  > type;
-};
-
-}  // namespace internal
-
-// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
-// fields of it matches a_matcher.  C++ doesn't support default
-// arguments for function templates, so we have to overload it.
-template <typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher>
-Args(const InnerMatcher& matcher) {
-  return internal::ArgsMatcher<InnerMatcher>(matcher);
-}
-
-template <int k1, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1>
-Args(const InnerMatcher& matcher) {
-  return internal::ArgsMatcher<InnerMatcher, k1>(matcher);
-}
-
-template <int k1, int k2, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2>
-Args(const InnerMatcher& matcher) {
-  return internal::ArgsMatcher<InnerMatcher, k1, k2>(matcher);
-}
-
-template <int k1, int k2, int k3, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3>
-Args(const InnerMatcher& matcher) {
-  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4>
-Args(const InnerMatcher& matcher) {
-  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5>
-Args(const InnerMatcher& matcher) {
-  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6>
-Args(const InnerMatcher& matcher) {
-  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7,
-    typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7>
-Args(const InnerMatcher& matcher) {
-  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6,
-      k7>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
-    typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8>
-Args(const InnerMatcher& matcher) {
-  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7,
-      k8>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
-    int k9, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8, k9>
-Args(const InnerMatcher& matcher) {
-  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8,
-      k9>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
-    int k9, int k10, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8, k9,
-    k10>
-Args(const InnerMatcher& matcher) {
-  return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8,
-      k9, k10>(matcher);
-}
-
-// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with
-// n elements, where the i-th element in the container must
-// match the i-th argument in the list.  Each argument of
-// ElementsAre() can be either a value or a matcher.  We support up to
-// 10 arguments.
-//
-// The use of DecayArray in the implementation allows ElementsAre()
-// to accept string literals, whose type is const char[N], but we
-// want to treat them as const char*.
-//
-// NOTE: Since ElementsAre() cares about the order of the elements, it
-// must not be used with containers whose elements's order is
-// undefined (e.g. hash_map).
-
-inline internal::ElementsAreMatcher<
-    ::testing::tuple<> >
-ElementsAre() {
-  typedef ::testing::tuple<> Args;
-  return internal::ElementsAreMatcher<Args>(Args());
-}
-
-template <typename T1>
-inline internal::ElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type> >
-ElementsAre(const T1& e1) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type> Args;
-  return internal::ElementsAreMatcher<Args>(Args(e1));
-}
-
-template <typename T1, typename T2>
-inline internal::ElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type> >
-ElementsAre(const T1& e1, const T2& e2) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type> Args;
-  return internal::ElementsAreMatcher<Args>(Args(e1, e2));
-}
-
-template <typename T1, typename T2, typename T3>
-inline internal::ElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type> Args;
-  return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3));
-}
-
-template <typename T1, typename T2, typename T3, typename T4>
-inline internal::ElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type> Args;
-  return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-inline internal::ElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type,
-        typename internal::DecayArray<T5>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
-    const T5& e5) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type,
-      typename internal::DecayArray<T5>::type> Args;
-  return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6>
-inline internal::ElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type,
-        typename internal::DecayArray<T5>::type,
-        typename internal::DecayArray<T6>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
-    const T5& e5, const T6& e6) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type,
-      typename internal::DecayArray<T5>::type,
-      typename internal::DecayArray<T6>::type> Args;
-  return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7>
-inline internal::ElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type,
-        typename internal::DecayArray<T5>::type,
-        typename internal::DecayArray<T6>::type,
-        typename internal::DecayArray<T7>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
-    const T5& e5, const T6& e6, const T7& e7) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type,
-      typename internal::DecayArray<T5>::type,
-      typename internal::DecayArray<T6>::type,
-      typename internal::DecayArray<T7>::type> Args;
-  return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6, e7));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8>
-inline internal::ElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type,
-        typename internal::DecayArray<T5>::type,
-        typename internal::DecayArray<T6>::type,
-        typename internal::DecayArray<T7>::type,
-        typename internal::DecayArray<T8>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
-    const T5& e5, const T6& e6, const T7& e7, const T8& e8) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type,
-      typename internal::DecayArray<T5>::type,
-      typename internal::DecayArray<T6>::type,
-      typename internal::DecayArray<T7>::type,
-      typename internal::DecayArray<T8>::type> Args;
-  return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6, e7,
-      e8));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9>
-inline internal::ElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type,
-        typename internal::DecayArray<T5>::type,
-        typename internal::DecayArray<T6>::type,
-        typename internal::DecayArray<T7>::type,
-        typename internal::DecayArray<T8>::type,
-        typename internal::DecayArray<T9>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
-    const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type,
-      typename internal::DecayArray<T5>::type,
-      typename internal::DecayArray<T6>::type,
-      typename internal::DecayArray<T7>::type,
-      typename internal::DecayArray<T8>::type,
-      typename internal::DecayArray<T9>::type> Args;
-  return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6, e7,
-      e8, e9));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10>
-inline internal::ElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type,
-        typename internal::DecayArray<T5>::type,
-        typename internal::DecayArray<T6>::type,
-        typename internal::DecayArray<T7>::type,
-        typename internal::DecayArray<T8>::type,
-        typename internal::DecayArray<T9>::type,
-        typename internal::DecayArray<T10>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
-    const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9,
-    const T10& e10) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type,
-      typename internal::DecayArray<T5>::type,
-      typename internal::DecayArray<T6>::type,
-      typename internal::DecayArray<T7>::type,
-      typename internal::DecayArray<T8>::type,
-      typename internal::DecayArray<T9>::type,
-      typename internal::DecayArray<T10>::type> Args;
-  return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6, e7,
-      e8, e9, e10));
-}
-
-// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension
-// that matches n elements in any order.  We support up to n=10 arguments.
-
-inline internal::UnorderedElementsAreMatcher<
-    ::testing::tuple<> >
-UnorderedElementsAre() {
-  typedef ::testing::tuple<> Args;
-  return internal::UnorderedElementsAreMatcher<Args>(Args());
-}
-
-template <typename T1>
-inline internal::UnorderedElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type> >
-UnorderedElementsAre(const T1& e1) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type> Args;
-  return internal::UnorderedElementsAreMatcher<Args>(Args(e1));
-}
-
-template <typename T1, typename T2>
-inline internal::UnorderedElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type> Args;
-  return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2));
-}
-
-template <typename T1, typename T2, typename T3>
-inline internal::UnorderedElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type> Args;
-  return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3));
-}
-
-template <typename T1, typename T2, typename T3, typename T4>
-inline internal::UnorderedElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type> Args;
-  return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-inline internal::UnorderedElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type,
-        typename internal::DecayArray<T5>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
-    const T5& e5) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type,
-      typename internal::DecayArray<T5>::type> Args;
-  return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6>
-inline internal::UnorderedElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type,
-        typename internal::DecayArray<T5>::type,
-        typename internal::DecayArray<T6>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
-    const T5& e5, const T6& e6) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type,
-      typename internal::DecayArray<T5>::type,
-      typename internal::DecayArray<T6>::type> Args;
-  return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5,
-      e6));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7>
-inline internal::UnorderedElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type,
-        typename internal::DecayArray<T5>::type,
-        typename internal::DecayArray<T6>::type,
-        typename internal::DecayArray<T7>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
-    const T5& e5, const T6& e6, const T7& e7) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type,
-      typename internal::DecayArray<T5>::type,
-      typename internal::DecayArray<T6>::type,
-      typename internal::DecayArray<T7>::type> Args;
-  return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5,
-      e6, e7));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8>
-inline internal::UnorderedElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type,
-        typename internal::DecayArray<T5>::type,
-        typename internal::DecayArray<T6>::type,
-        typename internal::DecayArray<T7>::type,
-        typename internal::DecayArray<T8>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
-    const T5& e5, const T6& e6, const T7& e7, const T8& e8) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type,
-      typename internal::DecayArray<T5>::type,
-      typename internal::DecayArray<T6>::type,
-      typename internal::DecayArray<T7>::type,
-      typename internal::DecayArray<T8>::type> Args;
-  return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5,
-      e6, e7, e8));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9>
-inline internal::UnorderedElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type,
-        typename internal::DecayArray<T5>::type,
-        typename internal::DecayArray<T6>::type,
-        typename internal::DecayArray<T7>::type,
-        typename internal::DecayArray<T8>::type,
-        typename internal::DecayArray<T9>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
-    const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type,
-      typename internal::DecayArray<T5>::type,
-      typename internal::DecayArray<T6>::type,
-      typename internal::DecayArray<T7>::type,
-      typename internal::DecayArray<T8>::type,
-      typename internal::DecayArray<T9>::type> Args;
-  return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5,
-      e6, e7, e8, e9));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10>
-inline internal::UnorderedElementsAreMatcher<
-    ::testing::tuple<
-        typename internal::DecayArray<T1>::type,
-        typename internal::DecayArray<T2>::type,
-        typename internal::DecayArray<T3>::type,
-        typename internal::DecayArray<T4>::type,
-        typename internal::DecayArray<T5>::type,
-        typename internal::DecayArray<T6>::type,
-        typename internal::DecayArray<T7>::type,
-        typename internal::DecayArray<T8>::type,
-        typename internal::DecayArray<T9>::type,
-        typename internal::DecayArray<T10>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
-    const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9,
-    const T10& e10) {
-  typedef ::testing::tuple<
-      typename internal::DecayArray<T1>::type,
-      typename internal::DecayArray<T2>::type,
-      typename internal::DecayArray<T3>::type,
-      typename internal::DecayArray<T4>::type,
-      typename internal::DecayArray<T5>::type,
-      typename internal::DecayArray<T6>::type,
-      typename internal::DecayArray<T7>::type,
-      typename internal::DecayArray<T8>::type,
-      typename internal::DecayArray<T9>::type,
-      typename internal::DecayArray<T10>::type> Args;
-  return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5,
-      e6, e7, e8, e9, e10));
-}
-
-// AllOf(m1, m2, ..., mk) matches any value that matches all of the given
-// sub-matchers.  AllOf is called fully qualified to prevent ADL from firing.
-
-template <typename M1, typename M2>
-inline typename internal::AllOfResult2<M1, M2>::type
-AllOf(M1 m1, M2 m2) {
-  return typename internal::AllOfResult2<M1, M2>::type(
-      m1,
-      m2);
-}
-
-template <typename M1, typename M2, typename M3>
-inline typename internal::AllOfResult3<M1, M2, M3>::type
-AllOf(M1 m1, M2 m2, M3 m3) {
-  return typename internal::AllOfResult3<M1, M2, M3>::type(
-      m1,
-      ::testing::AllOf(m2, m3));
-}
-
-template <typename M1, typename M2, typename M3, typename M4>
-inline typename internal::AllOfResult4<M1, M2, M3, M4>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4) {
-  return typename internal::AllOfResult4<M1, M2, M3, M4>::type(
-      ::testing::AllOf(m1, m2),
-      ::testing::AllOf(m3, m4));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5>
-inline typename internal::AllOfResult5<M1, M2, M3, M4, M5>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5) {
-  return typename internal::AllOfResult5<M1, M2, M3, M4, M5>::type(
-      ::testing::AllOf(m1, m2),
-      ::testing::AllOf(m3, m4, m5));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6>
-inline typename internal::AllOfResult6<M1, M2, M3, M4, M5, M6>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6) {
-  return typename internal::AllOfResult6<M1, M2, M3, M4, M5, M6>::type(
-      ::testing::AllOf(m1, m2, m3),
-      ::testing::AllOf(m4, m5, m6));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7>
-inline typename internal::AllOfResult7<M1, M2, M3, M4, M5, M6, M7>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7) {
-  return typename internal::AllOfResult7<M1, M2, M3, M4, M5, M6, M7>::type(
-      ::testing::AllOf(m1, m2, m3),
-      ::testing::AllOf(m4, m5, m6, m7));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7, typename M8>
-inline typename internal::AllOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8) {
-  return typename internal::AllOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type(
-      ::testing::AllOf(m1, m2, m3, m4),
-      ::testing::AllOf(m5, m6, m7, m8));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7, typename M8, typename M9>
-inline typename internal::AllOfResult9<M1, M2, M3, M4, M5, M6, M7, M8, M9>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9) {
-  return typename internal::AllOfResult9<M1, M2, M3, M4, M5, M6, M7, M8,
-      M9>::type(
-      ::testing::AllOf(m1, m2, m3, m4),
-      ::testing::AllOf(m5, m6, m7, m8, m9));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7, typename M8, typename M9, typename M10>
-inline typename internal::AllOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9,
-    M10>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) {
-  return typename internal::AllOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9,
-      M10>::type(
-      ::testing::AllOf(m1, m2, m3, m4, m5),
-      ::testing::AllOf(m6, m7, m8, m9, m10));
-}
-
-// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given
-// sub-matchers.  AnyOf is called fully qualified to prevent ADL from firing.
-
-template <typename M1, typename M2>
-inline typename internal::AnyOfResult2<M1, M2>::type
-AnyOf(M1 m1, M2 m2) {
-  return typename internal::AnyOfResult2<M1, M2>::type(
-      m1,
-      m2);
-}
-
-template <typename M1, typename M2, typename M3>
-inline typename internal::AnyOfResult3<M1, M2, M3>::type
-AnyOf(M1 m1, M2 m2, M3 m3) {
-  return typename internal::AnyOfResult3<M1, M2, M3>::type(
-      m1,
-      ::testing::AnyOf(m2, m3));
-}
-
-template <typename M1, typename M2, typename M3, typename M4>
-inline typename internal::AnyOfResult4<M1, M2, M3, M4>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4) {
-  return typename internal::AnyOfResult4<M1, M2, M3, M4>::type(
-      ::testing::AnyOf(m1, m2),
-      ::testing::AnyOf(m3, m4));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5>
-inline typename internal::AnyOfResult5<M1, M2, M3, M4, M5>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5) {
-  return typename internal::AnyOfResult5<M1, M2, M3, M4, M5>::type(
-      ::testing::AnyOf(m1, m2),
-      ::testing::AnyOf(m3, m4, m5));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6>
-inline typename internal::AnyOfResult6<M1, M2, M3, M4, M5, M6>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6) {
-  return typename internal::AnyOfResult6<M1, M2, M3, M4, M5, M6>::type(
-      ::testing::AnyOf(m1, m2, m3),
-      ::testing::AnyOf(m4, m5, m6));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7>
-inline typename internal::AnyOfResult7<M1, M2, M3, M4, M5, M6, M7>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7) {
-  return typename internal::AnyOfResult7<M1, M2, M3, M4, M5, M6, M7>::type(
-      ::testing::AnyOf(m1, m2, m3),
-      ::testing::AnyOf(m4, m5, m6, m7));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7, typename M8>
-inline typename internal::AnyOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8) {
-  return typename internal::AnyOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type(
-      ::testing::AnyOf(m1, m2, m3, m4),
-      ::testing::AnyOf(m5, m6, m7, m8));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7, typename M8, typename M9>
-inline typename internal::AnyOfResult9<M1, M2, M3, M4, M5, M6, M7, M8, M9>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9) {
-  return typename internal::AnyOfResult9<M1, M2, M3, M4, M5, M6, M7, M8,
-      M9>::type(
-      ::testing::AnyOf(m1, m2, m3, m4),
-      ::testing::AnyOf(m5, m6, m7, m8, m9));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
-    typename M6, typename M7, typename M8, typename M9, typename M10>
-inline typename internal::AnyOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9,
-    M10>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) {
-  return typename internal::AnyOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9,
-      M10>::type(
-      ::testing::AnyOf(m1, m2, m3, m4, m5),
-      ::testing::AnyOf(m6, m7, m8, m9, m10));
-}
-
-}  // namespace testing
-
-
 // The MATCHER* family of macros can be used in a namespace scope to
 // define custom matchers easily.
 //
@@ -13738,7 +11975,7 @@
 //   using testing::PrintToString;
 //
 //   MATCHER_P2(InClosedRange, low, hi,
-//       string(negation ? "is not" : "is") + " in range [" +
+//       std::string(negation ? "is not" : "is") + " in range [" +
 //       PrintToString(low) + ", " + PrintToString(hi) + "]") {
 //     return low <= arg && arg <= hi;
 //   }
@@ -13846,18 +12083,21 @@
 // ================
 //
 // To learn more about using these macros, please search for 'MATCHER'
-// on http://code.google.com/p/googlemock/wiki/CookBook.
+// on
+// https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md
 
 #define MATCHER(name, description)\
   class name##Matcher {\
    public:\
     template <typename arg_type>\
-    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+    class gmock_Impl : public ::testing::MatcherInterface<\
+        GTEST_REFERENCE_TO_CONST_(arg_type)> {\
      public:\
       gmock_Impl()\
            {}\
       virtual bool MatchAndExplain(\
-          arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+          GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+          ::testing::MatchResultListener* result_listener) const;\
       virtual void DescribeTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(false);\
       }\
@@ -13865,16 +12105,16 @@
         *gmock_os << FormatDescription(true);\
       }\
      private:\
-      ::testing::internal::string FormatDescription(bool negation) const {\
-        const ::testing::internal::string gmock_description = (description);\
-        if (!gmock_description.empty())\
+      ::std::string FormatDescription(bool negation) const {\
+        ::std::string gmock_description = (description);\
+        if (!gmock_description.empty()) {\
           return gmock_description;\
+        }\
         return ::testing::internal::FormatMatcherDescription(\
             negation, #name, \
             ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
-                ::testing::tuple<>()));\
+                ::std::tuple<>()));\
       }\
-      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
     };\
     template <typename arg_type>\
     operator ::testing::Matcher<arg_type>() const {\
@@ -13884,14 +12124,13 @@
     name##Matcher() {\
     }\
    private:\
-    GTEST_DISALLOW_ASSIGN_(name##Matcher);\
   };\
   inline name##Matcher name() {\
     return name##Matcher();\
   }\
   template <typename arg_type>\
   bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain(\
-      arg_type arg, \
+      GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
       ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
           const
 
@@ -13900,41 +12139,42 @@
   class name##MatcherP {\
    public:\
     template <typename arg_type>\
-    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+    class gmock_Impl : public ::testing::MatcherInterface<\
+        GTEST_REFERENCE_TO_CONST_(arg_type)> {\
      public:\
       explicit gmock_Impl(p0##_type gmock_p0)\
-           : p0(gmock_p0) {}\
+           : p0(::std::move(gmock_p0)) {}\
       virtual bool MatchAndExplain(\
-          arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+          GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+          ::testing::MatchResultListener* result_listener) const;\
       virtual void DescribeTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(false);\
       }\
       virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(true);\
       }\
-      p0##_type p0;\
+      p0##_type const p0;\
      private:\
-      ::testing::internal::string FormatDescription(bool negation) const {\
-        const ::testing::internal::string gmock_description = (description);\
-        if (!gmock_description.empty())\
+      ::std::string FormatDescription(bool negation) const {\
+        ::std::string gmock_description = (description);\
+        if (!gmock_description.empty()) {\
           return gmock_description;\
+        }\
         return ::testing::internal::FormatMatcherDescription(\
             negation, #name, \
             ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
-                ::testing::tuple<p0##_type>(p0)));\
+                ::std::tuple<p0##_type>(p0)));\
       }\
-      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
     };\
     template <typename arg_type>\
     operator ::testing::Matcher<arg_type>() const {\
       return ::testing::Matcher<arg_type>(\
           new gmock_Impl<arg_type>(p0));\
     }\
-    explicit name##MatcherP(p0##_type gmock_p0) : p0(gmock_p0) {\
+    explicit name##MatcherP(p0##_type gmock_p0) : p0(::std::move(gmock_p0)) {\
     }\
-    p0##_type p0;\
+    p0##_type const p0;\
    private:\
-    GTEST_DISALLOW_ASSIGN_(name##MatcherP);\
   };\
   template <typename p0##_type>\
   inline name##MatcherP<p0##_type> name(p0##_type p0) {\
@@ -13943,7 +12183,7 @@
   template <typename p0##_type>\
   template <typename arg_type>\
   bool name##MatcherP<p0##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
-      arg_type arg, \
+      GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
       ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
           const
 
@@ -13952,44 +12192,46 @@
   class name##MatcherP2 {\
    public:\
     template <typename arg_type>\
-    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+    class gmock_Impl : public ::testing::MatcherInterface<\
+        GTEST_REFERENCE_TO_CONST_(arg_type)> {\
      public:\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1)\
-           : p0(gmock_p0), p1(gmock_p1) {}\
+           : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)) {}\
       virtual bool MatchAndExplain(\
-          arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+          GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+          ::testing::MatchResultListener* result_listener) const;\
       virtual void DescribeTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(false);\
       }\
       virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(true);\
       }\
-      p0##_type p0;\
-      p1##_type p1;\
+      p0##_type const p0;\
+      p1##_type const p1;\
      private:\
-      ::testing::internal::string FormatDescription(bool negation) const {\
-        const ::testing::internal::string gmock_description = (description);\
-        if (!gmock_description.empty())\
+      ::std::string FormatDescription(bool negation) const {\
+        ::std::string gmock_description = (description);\
+        if (!gmock_description.empty()) {\
           return gmock_description;\
+        }\
         return ::testing::internal::FormatMatcherDescription(\
             negation, #name, \
             ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
-                ::testing::tuple<p0##_type, p1##_type>(p0, p1)));\
+                ::std::tuple<p0##_type, p1##_type>(p0, p1)));\
       }\
-      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
     };\
     template <typename arg_type>\
     operator ::testing::Matcher<arg_type>() const {\
       return ::testing::Matcher<arg_type>(\
           new gmock_Impl<arg_type>(p0, p1));\
     }\
-    name##MatcherP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
-        p1(gmock_p1) {\
+    name##MatcherP2(p0##_type gmock_p0, \
+        p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)) {\
     }\
-    p0##_type p0;\
-    p1##_type p1;\
+    p0##_type const p0;\
+    p1##_type const p1;\
    private:\
-    GTEST_DISALLOW_ASSIGN_(name##MatcherP2);\
   };\
   template <typename p0##_type, typename p1##_type>\
   inline name##MatcherP2<p0##_type, p1##_type> name(p0##_type p0, \
@@ -14000,7 +12242,7 @@
   template <typename arg_type>\
   bool name##MatcherP2<p0##_type, \
       p1##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
-      arg_type arg, \
+      GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
       ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
           const
 
@@ -14009,33 +12251,35 @@
   class name##MatcherP3 {\
    public:\
     template <typename arg_type>\
-    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+    class gmock_Impl : public ::testing::MatcherInterface<\
+        GTEST_REFERENCE_TO_CONST_(arg_type)> {\
      public:\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2)\
-           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\
+           : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+               p2(::std::move(gmock_p2)) {}\
       virtual bool MatchAndExplain(\
-          arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+          GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+          ::testing::MatchResultListener* result_listener) const;\
       virtual void DescribeTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(false);\
       }\
       virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(true);\
       }\
-      p0##_type p0;\
-      p1##_type p1;\
-      p2##_type p2;\
+      p0##_type const p0;\
+      p1##_type const p1;\
+      p2##_type const p2;\
      private:\
-      ::testing::internal::string FormatDescription(bool negation) const {\
-        const ::testing::internal::string gmock_description = (description);\
-        if (!gmock_description.empty())\
+      ::std::string FormatDescription(bool negation) const {\
+        ::std::string gmock_description = (description);\
+        if (!gmock_description.empty()) {\
           return gmock_description;\
+        }\
         return ::testing::internal::FormatMatcherDescription(\
             negation, #name, \
             ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
-                ::testing::tuple<p0##_type, p1##_type, p2##_type>(p0, p1, \
-                    p2)));\
+                ::std::tuple<p0##_type, p1##_type, p2##_type>(p0, p1, p2)));\
       }\
-      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
     };\
     template <typename arg_type>\
     operator ::testing::Matcher<arg_type>() const {\
@@ -14043,13 +12287,13 @@
           new gmock_Impl<arg_type>(p0, p1, p2));\
     }\
     name##MatcherP3(p0##_type gmock_p0, p1##_type gmock_p1, \
-        p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {\
+        p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)) {\
     }\
-    p0##_type p0;\
-    p1##_type p1;\
-    p2##_type p2;\
+    p0##_type const p0;\
+    p1##_type const p1;\
+    p2##_type const p2;\
    private:\
-    GTEST_DISALLOW_ASSIGN_(name##MatcherP3);\
   };\
   template <typename p0##_type, typename p1##_type, typename p2##_type>\
   inline name##MatcherP3<p0##_type, p1##_type, p2##_type> name(p0##_type p0, \
@@ -14060,7 +12304,7 @@
   template <typename arg_type>\
   bool name##MatcherP3<p0##_type, p1##_type, \
       p2##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
-      arg_type arg, \
+      GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
       ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
           const
 
@@ -14070,35 +12314,38 @@
   class name##MatcherP4 {\
    public:\
     template <typename arg_type>\
-    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+    class gmock_Impl : public ::testing::MatcherInterface<\
+        GTEST_REFERENCE_TO_CONST_(arg_type)> {\
      public:\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
           p3##_type gmock_p3)\
-           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3) {}\
+           : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+               p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)) {}\
       virtual bool MatchAndExplain(\
-          arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+          GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+          ::testing::MatchResultListener* result_listener) const;\
       virtual void DescribeTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(false);\
       }\
       virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(true);\
       }\
-      p0##_type p0;\
-      p1##_type p1;\
-      p2##_type p2;\
-      p3##_type p3;\
+      p0##_type const p0;\
+      p1##_type const p1;\
+      p2##_type const p2;\
+      p3##_type const p3;\
      private:\
-      ::testing::internal::string FormatDescription(bool negation) const {\
-        const ::testing::internal::string gmock_description = (description);\
-        if (!gmock_description.empty())\
+      ::std::string FormatDescription(bool negation) const {\
+        ::std::string gmock_description = (description);\
+        if (!gmock_description.empty()) {\
           return gmock_description;\
+        }\
         return ::testing::internal::FormatMatcherDescription(\
             negation, #name, \
             ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
-                ::testing::tuple<p0##_type, p1##_type, p2##_type, \
-                    p3##_type>(p0, p1, p2, p3)));\
+                ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type>(p0, \
+                    p1, p2, p3)));\
       }\
-      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
     };\
     template <typename arg_type>\
     operator ::testing::Matcher<arg_type>() const {\
@@ -14106,15 +12353,15 @@
           new gmock_Impl<arg_type>(p0, p1, p2, p3));\
     }\
     name##MatcherP4(p0##_type gmock_p0, p1##_type gmock_p1, \
-        p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \
-        p2(gmock_p2), p3(gmock_p3) {\
+        p2##_type gmock_p2, p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3)) {\
     }\
-    p0##_type p0;\
-    p1##_type p1;\
-    p2##_type p2;\
-    p3##_type p3;\
+    p0##_type const p0;\
+    p1##_type const p1;\
+    p2##_type const p2;\
+    p3##_type const p3;\
    private:\
-    GTEST_DISALLOW_ASSIGN_(name##MatcherP4);\
   };\
   template <typename p0##_type, typename p1##_type, typename p2##_type, \
       typename p3##_type>\
@@ -14129,7 +12376,7 @@
   template <typename arg_type>\
   bool name##MatcherP4<p0##_type, p1##_type, p2##_type, \
       p3##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
-      arg_type arg, \
+      GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
       ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
           const
 
@@ -14139,37 +12386,40 @@
   class name##MatcherP5 {\
    public:\
     template <typename arg_type>\
-    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+    class gmock_Impl : public ::testing::MatcherInterface<\
+        GTEST_REFERENCE_TO_CONST_(arg_type)> {\
      public:\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
           p3##_type gmock_p3, p4##_type gmock_p4)\
-           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
-               p4(gmock_p4) {}\
+           : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+               p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
+               p4(::std::move(gmock_p4)) {}\
       virtual bool MatchAndExplain(\
-          arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+          GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+          ::testing::MatchResultListener* result_listener) const;\
       virtual void DescribeTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(false);\
       }\
       virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(true);\
       }\
-      p0##_type p0;\
-      p1##_type p1;\
-      p2##_type p2;\
-      p3##_type p3;\
-      p4##_type p4;\
+      p0##_type const p0;\
+      p1##_type const p1;\
+      p2##_type const p2;\
+      p3##_type const p3;\
+      p4##_type const p4;\
      private:\
-      ::testing::internal::string FormatDescription(bool negation) const {\
-        const ::testing::internal::string gmock_description = (description);\
-        if (!gmock_description.empty())\
+      ::std::string FormatDescription(bool negation) const {\
+        ::std::string gmock_description = (description);\
+        if (!gmock_description.empty()) {\
           return gmock_description;\
+        }\
         return ::testing::internal::FormatMatcherDescription(\
             negation, #name, \
             ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
-                ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+                ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
                     p4##_type>(p0, p1, p2, p3, p4)));\
       }\
-      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
     };\
     template <typename arg_type>\
     operator ::testing::Matcher<arg_type>() const {\
@@ -14178,16 +12428,16 @@
     }\
     name##MatcherP5(p0##_type gmock_p0, p1##_type gmock_p1, \
         p2##_type gmock_p2, p3##_type gmock_p3, \
-        p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-        p3(gmock_p3), p4(gmock_p4) {\
+        p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)) {\
     }\
-    p0##_type p0;\
-    p1##_type p1;\
-    p2##_type p2;\
-    p3##_type p3;\
-    p4##_type p4;\
+    p0##_type const p0;\
+    p1##_type const p1;\
+    p2##_type const p2;\
+    p3##_type const p3;\
+    p4##_type const p4;\
    private:\
-    GTEST_DISALLOW_ASSIGN_(name##MatcherP5);\
   };\
   template <typename p0##_type, typename p1##_type, typename p2##_type, \
       typename p3##_type, typename p4##_type>\
@@ -14202,7 +12452,7 @@
   template <typename arg_type>\
   bool name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, \
       p4##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
-      arg_type arg, \
+      GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
       ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
           const
 
@@ -14212,38 +12462,41 @@
   class name##MatcherP6 {\
    public:\
     template <typename arg_type>\
-    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+    class gmock_Impl : public ::testing::MatcherInterface<\
+        GTEST_REFERENCE_TO_CONST_(arg_type)> {\
      public:\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
           p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5)\
-           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
-               p4(gmock_p4), p5(gmock_p5) {}\
+           : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+               p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
+               p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)) {}\
       virtual bool MatchAndExplain(\
-          arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+          GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+          ::testing::MatchResultListener* result_listener) const;\
       virtual void DescribeTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(false);\
       }\
       virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(true);\
       }\
-      p0##_type p0;\
-      p1##_type p1;\
-      p2##_type p2;\
-      p3##_type p3;\
-      p4##_type p4;\
-      p5##_type p5;\
+      p0##_type const p0;\
+      p1##_type const p1;\
+      p2##_type const p2;\
+      p3##_type const p3;\
+      p4##_type const p4;\
+      p5##_type const p5;\
      private:\
-      ::testing::internal::string FormatDescription(bool negation) const {\
-        const ::testing::internal::string gmock_description = (description);\
-        if (!gmock_description.empty())\
+      ::std::string FormatDescription(bool negation) const {\
+        ::std::string gmock_description = (description);\
+        if (!gmock_description.empty()) {\
           return gmock_description;\
+        }\
         return ::testing::internal::FormatMatcherDescription(\
             negation, #name, \
             ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
-                ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+                ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
                     p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5)));\
       }\
-      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
     };\
     template <typename arg_type>\
     operator ::testing::Matcher<arg_type>() const {\
@@ -14252,17 +12505,18 @@
     }\
     name##MatcherP6(p0##_type gmock_p0, p1##_type gmock_p1, \
         p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
-        p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {\
+        p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+        p5(::std::move(gmock_p5)) {\
     }\
-    p0##_type p0;\
-    p1##_type p1;\
-    p2##_type p2;\
-    p3##_type p3;\
-    p4##_type p4;\
-    p5##_type p5;\
+    p0##_type const p0;\
+    p1##_type const p1;\
+    p2##_type const p2;\
+    p3##_type const p3;\
+    p4##_type const p4;\
+    p5##_type const p5;\
    private:\
-    GTEST_DISALLOW_ASSIGN_(name##MatcherP6);\
   };\
   template <typename p0##_type, typename p1##_type, typename p2##_type, \
       typename p3##_type, typename p4##_type, typename p5##_type>\
@@ -14277,7 +12531,7 @@
   template <typename arg_type>\
   bool name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
       p5##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
-      arg_type arg, \
+      GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
       ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
           const
 
@@ -14288,41 +12542,45 @@
   class name##MatcherP7 {\
    public:\
     template <typename arg_type>\
-    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+    class gmock_Impl : public ::testing::MatcherInterface<\
+        GTEST_REFERENCE_TO_CONST_(arg_type)> {\
      public:\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
           p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
           p6##_type gmock_p6)\
-           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
-               p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\
+           : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+               p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
+               p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \
+               p6(::std::move(gmock_p6)) {}\
       virtual bool MatchAndExplain(\
-          arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+          GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+          ::testing::MatchResultListener* result_listener) const;\
       virtual void DescribeTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(false);\
       }\
       virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(true);\
       }\
-      p0##_type p0;\
-      p1##_type p1;\
-      p2##_type p2;\
-      p3##_type p3;\
-      p4##_type p4;\
-      p5##_type p5;\
-      p6##_type p6;\
+      p0##_type const p0;\
+      p1##_type const p1;\
+      p2##_type const p2;\
+      p3##_type const p3;\
+      p4##_type const p4;\
+      p5##_type const p5;\
+      p6##_type const p6;\
      private:\
-      ::testing::internal::string FormatDescription(bool negation) const {\
-        const ::testing::internal::string gmock_description = (description);\
-        if (!gmock_description.empty())\
+      ::std::string FormatDescription(bool negation) const {\
+        ::std::string gmock_description = (description);\
+        if (!gmock_description.empty()) {\
           return gmock_description;\
+        }\
         return ::testing::internal::FormatMatcherDescription(\
             negation, #name, \
             ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
-                ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+                ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
                     p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, \
                     p6)));\
       }\
-      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
     };\
     template <typename arg_type>\
     operator ::testing::Matcher<arg_type>() const {\
@@ -14331,19 +12589,19 @@
     }\
     name##MatcherP7(p0##_type gmock_p0, p1##_type gmock_p1, \
         p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
-        p5##_type gmock_p5, p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), \
-        p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \
-        p6(gmock_p6) {\
+        p5##_type gmock_p5, p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+        p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)) {\
     }\
-    p0##_type p0;\
-    p1##_type p1;\
-    p2##_type p2;\
-    p3##_type p3;\
-    p4##_type p4;\
-    p5##_type p5;\
-    p6##_type p6;\
+    p0##_type const p0;\
+    p1##_type const p1;\
+    p2##_type const p2;\
+    p3##_type const p3;\
+    p4##_type const p4;\
+    p5##_type const p5;\
+    p6##_type const p6;\
    private:\
-    GTEST_DISALLOW_ASSIGN_(name##MatcherP7);\
   };\
   template <typename p0##_type, typename p1##_type, typename p2##_type, \
       typename p3##_type, typename p4##_type, typename p5##_type, \
@@ -14361,7 +12619,7 @@
   template <typename arg_type>\
   bool name##MatcherP7<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
       p5##_type, p6##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
-      arg_type arg, \
+      GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
       ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
           const
 
@@ -14372,42 +12630,46 @@
   class name##MatcherP8 {\
    public:\
     template <typename arg_type>\
-    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+    class gmock_Impl : public ::testing::MatcherInterface<\
+        GTEST_REFERENCE_TO_CONST_(arg_type)> {\
      public:\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
           p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
           p6##_type gmock_p6, p7##_type gmock_p7)\
-           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
-               p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\
+           : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+               p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
+               p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \
+               p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)) {}\
       virtual bool MatchAndExplain(\
-          arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+          GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+          ::testing::MatchResultListener* result_listener) const;\
       virtual void DescribeTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(false);\
       }\
       virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(true);\
       }\
-      p0##_type p0;\
-      p1##_type p1;\
-      p2##_type p2;\
-      p3##_type p3;\
-      p4##_type p4;\
-      p5##_type p5;\
-      p6##_type p6;\
-      p7##_type p7;\
+      p0##_type const p0;\
+      p1##_type const p1;\
+      p2##_type const p2;\
+      p3##_type const p3;\
+      p4##_type const p4;\
+      p5##_type const p5;\
+      p6##_type const p6;\
+      p7##_type const p7;\
      private:\
-      ::testing::internal::string FormatDescription(bool negation) const {\
-        const ::testing::internal::string gmock_description = (description);\
-        if (!gmock_description.empty())\
+      ::std::string FormatDescription(bool negation) const {\
+        ::std::string gmock_description = (description);\
+        if (!gmock_description.empty()) {\
           return gmock_description;\
+        }\
         return ::testing::internal::FormatMatcherDescription(\
             negation, #name, \
             ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
-                ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+                ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
                     p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, \
                     p3, p4, p5, p6, p7)));\
       }\
-      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
     };\
     template <typename arg_type>\
     operator ::testing::Matcher<arg_type>() const {\
@@ -14417,20 +12679,21 @@
     name##MatcherP8(p0##_type gmock_p0, p1##_type gmock_p1, \
         p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
         p5##_type gmock_p5, p6##_type gmock_p6, \
-        p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
-        p7(gmock_p7) {\
+        p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+        p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
+        p7(::std::move(gmock_p7)) {\
     }\
-    p0##_type p0;\
-    p1##_type p1;\
-    p2##_type p2;\
-    p3##_type p3;\
-    p4##_type p4;\
-    p5##_type p5;\
-    p6##_type p6;\
-    p7##_type p7;\
+    p0##_type const p0;\
+    p1##_type const p1;\
+    p2##_type const p2;\
+    p3##_type const p3;\
+    p4##_type const p4;\
+    p5##_type const p5;\
+    p6##_type const p6;\
+    p7##_type const p7;\
    private:\
-    GTEST_DISALLOW_ASSIGN_(name##MatcherP8);\
   };\
   template <typename p0##_type, typename p1##_type, typename p2##_type, \
       typename p3##_type, typename p4##_type, typename p5##_type, \
@@ -14450,7 +12713,7 @@
   bool name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
       p5##_type, p6##_type, \
       p7##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
-      arg_type arg, \
+      GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
       ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
           const
 
@@ -14461,44 +12724,48 @@
   class name##MatcherP9 {\
    public:\
     template <typename arg_type>\
-    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+    class gmock_Impl : public ::testing::MatcherInterface<\
+        GTEST_REFERENCE_TO_CONST_(arg_type)> {\
      public:\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
           p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
           p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8)\
-           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
-               p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
-               p8(gmock_p8) {}\
+           : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+               p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
+               p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \
+               p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)), \
+               p8(::std::move(gmock_p8)) {}\
       virtual bool MatchAndExplain(\
-          arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+          GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+          ::testing::MatchResultListener* result_listener) const;\
       virtual void DescribeTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(false);\
       }\
       virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(true);\
       }\
-      p0##_type p0;\
-      p1##_type p1;\
-      p2##_type p2;\
-      p3##_type p3;\
-      p4##_type p4;\
-      p5##_type p5;\
-      p6##_type p6;\
-      p7##_type p7;\
-      p8##_type p8;\
+      p0##_type const p0;\
+      p1##_type const p1;\
+      p2##_type const p2;\
+      p3##_type const p3;\
+      p4##_type const p4;\
+      p5##_type const p5;\
+      p6##_type const p6;\
+      p7##_type const p7;\
+      p8##_type const p8;\
      private:\
-      ::testing::internal::string FormatDescription(bool negation) const {\
-        const ::testing::internal::string gmock_description = (description);\
-        if (!gmock_description.empty())\
+      ::std::string FormatDescription(bool negation) const {\
+        ::std::string gmock_description = (description);\
+        if (!gmock_description.empty()) {\
           return gmock_description;\
+        }\
         return ::testing::internal::FormatMatcherDescription(\
             negation, #name, \
             ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
-                ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+                ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
                     p4##_type, p5##_type, p6##_type, p7##_type, \
                     p8##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8)));\
       }\
-      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
     };\
     template <typename arg_type>\
     operator ::testing::Matcher<arg_type>() const {\
@@ -14508,21 +12775,22 @@
     name##MatcherP9(p0##_type gmock_p0, p1##_type gmock_p1, \
         p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
         p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
-        p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
-        p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
-        p8(gmock_p8) {\
+        p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+        p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
+        p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)) {\
     }\
-    p0##_type p0;\
-    p1##_type p1;\
-    p2##_type p2;\
-    p3##_type p3;\
-    p4##_type p4;\
-    p5##_type p5;\
-    p6##_type p6;\
-    p7##_type p7;\
-    p8##_type p8;\
+    p0##_type const p0;\
+    p1##_type const p1;\
+    p2##_type const p2;\
+    p3##_type const p3;\
+    p4##_type const p4;\
+    p5##_type const p5;\
+    p6##_type const p6;\
+    p7##_type const p7;\
+    p8##_type const p8;\
    private:\
-    GTEST_DISALLOW_ASSIGN_(name##MatcherP9);\
   };\
   template <typename p0##_type, typename p1##_type, typename p2##_type, \
       typename p3##_type, typename p4##_type, typename p5##_type, \
@@ -14543,7 +12811,7 @@
   bool name##MatcherP9<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
       p5##_type, p6##_type, p7##_type, \
       p8##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
-      arg_type arg, \
+      GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
       ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
           const
 
@@ -14555,46 +12823,50 @@
   class name##MatcherP10 {\
    public:\
     template <typename arg_type>\
-    class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+    class gmock_Impl : public ::testing::MatcherInterface<\
+        GTEST_REFERENCE_TO_CONST_(arg_type)> {\
      public:\
       gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
           p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
           p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
           p9##_type gmock_p9)\
-           : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
-               p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
-               p8(gmock_p8), p9(gmock_p9) {}\
+           : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+               p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
+               p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \
+               p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)), \
+               p8(::std::move(gmock_p8)), p9(::std::move(gmock_p9)) {}\
       virtual bool MatchAndExplain(\
-          arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+          GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+          ::testing::MatchResultListener* result_listener) const;\
       virtual void DescribeTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(false);\
       }\
       virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
         *gmock_os << FormatDescription(true);\
       }\
-      p0##_type p0;\
-      p1##_type p1;\
-      p2##_type p2;\
-      p3##_type p3;\
-      p4##_type p4;\
-      p5##_type p5;\
-      p6##_type p6;\
-      p7##_type p7;\
-      p8##_type p8;\
-      p9##_type p9;\
+      p0##_type const p0;\
+      p1##_type const p1;\
+      p2##_type const p2;\
+      p3##_type const p3;\
+      p4##_type const p4;\
+      p5##_type const p5;\
+      p6##_type const p6;\
+      p7##_type const p7;\
+      p8##_type const p8;\
+      p9##_type const p9;\
      private:\
-      ::testing::internal::string FormatDescription(bool negation) const {\
-        const ::testing::internal::string gmock_description = (description);\
-        if (!gmock_description.empty())\
+      ::std::string FormatDescription(bool negation) const {\
+        ::std::string gmock_description = (description);\
+        if (!gmock_description.empty()) {\
           return gmock_description;\
+        }\
         return ::testing::internal::FormatMatcherDescription(\
             negation, #name, \
             ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
-                ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+                ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
                     p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \
                     p9##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)));\
       }\
-      GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
     };\
     template <typename arg_type>\
     operator ::testing::Matcher<arg_type>() const {\
@@ -14604,22 +12876,24 @@
     name##MatcherP10(p0##_type gmock_p0, p1##_type gmock_p1, \
         p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
         p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
-        p8##_type gmock_p8, p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), \
-        p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
-        p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {\
+        p8##_type gmock_p8, p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \
+        p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+        p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+        p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
+        p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \
+        p9(::std::move(gmock_p9)) {\
     }\
-    p0##_type p0;\
-    p1##_type p1;\
-    p2##_type p2;\
-    p3##_type p3;\
-    p4##_type p4;\
-    p5##_type p5;\
-    p6##_type p6;\
-    p7##_type p7;\
-    p8##_type p8;\
-    p9##_type p9;\
+    p0##_type const p0;\
+    p1##_type const p1;\
+    p2##_type const p2;\
+    p3##_type const p3;\
+    p4##_type const p4;\
+    p5##_type const p5;\
+    p6##_type const p6;\
+    p7##_type const p7;\
+    p8##_type const p8;\
+    p9##_type const p9;\
    private:\
-    GTEST_DISALLOW_ASSIGN_(name##MatcherP10);\
   };\
   template <typename p0##_type, typename p1##_type, typename p2##_type, \
       typename p3##_type, typename p4##_type, typename p5##_type, \
@@ -14642,7 +12916,7 @@
   bool name##MatcherP10<p0##_type, p1##_type, p2##_type, p3##_type, \
       p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \
       p9##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
-      arg_type arg, \
+      GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
       ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
           const
 
@@ -14675,69 +12949,24 @@
 // 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: wan@google.com (Zhanyong Wan)
+
 
 // Google Mock - a framework for writing C++ mock classes.
 //
 // This file implements some actions that depend on gmock-generated-actions.h.
 
+// GOOGLETEST_CM0002 DO NOT DELETE
+
 #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
 #define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
 
 #include <algorithm>
+#include <type_traits>
 
 
 namespace testing {
 namespace internal {
 
-// Implements the Invoke(f) action.  The template argument
-// FunctionImpl is the implementation type of f, which can be either a
-// function pointer or a functor.  Invoke(f) can be used as an
-// Action<F> as long as f's type is compatible with F (i.e. f can be
-// assigned to a tr1::function<F>).
-template <typename FunctionImpl>
-class InvokeAction {
- public:
-  // The c'tor makes a copy of function_impl (either a function
-  // pointer or a functor).
-  explicit InvokeAction(FunctionImpl function_impl)
-      : function_impl_(function_impl) {}
-
-  template <typename Result, typename ArgumentTuple>
-  Result Perform(const ArgumentTuple& args) {
-    return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
-  }
-
- private:
-  FunctionImpl function_impl_;
-
-  GTEST_DISALLOW_ASSIGN_(InvokeAction);
-};
-
-// Implements the Invoke(object_ptr, &Class::Method) action.
-template <class Class, typename MethodPtr>
-class InvokeMethodAction {
- public:
-  InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
-      : method_ptr_(method_ptr), obj_ptr_(obj_ptr) {}
-
-  template <typename Result, typename ArgumentTuple>
-  Result Perform(const ArgumentTuple& args) const {
-    return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
-        obj_ptr_, method_ptr_, args);
-  }
-
- private:
-  // The order of these members matters.  Reversing the order can trigger
-  // warning C4121 in MSVC (see
-  // http://computer-programming-forum.com/7-vc.net/6fbc30265f860ad1.htm ).
-  const MethodPtr method_ptr_;
-  Class* const obj_ptr_;
-
-  GTEST_DISALLOW_ASSIGN_(InvokeMethodAction);
-};
-
 // An internal replacement for std::copy which mimics its behavior. This is
 // necessary because Visual Studio deprecates ::std::copy, issuing warning 4996.
 // However Visual Studio 2010 and later do not honor #pragmas which disable that
@@ -14756,45 +12985,6 @@
 
 // Various overloads for Invoke().
 
-// Creates an action that invokes 'function_impl' with the mock
-// function's arguments.
-template <typename FunctionImpl>
-PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
-    FunctionImpl function_impl) {
-  return MakePolymorphicAction(
-      internal::InvokeAction<FunctionImpl>(function_impl));
-}
-
-// Creates an action that invokes the given method on the given object
-// with the mock function's arguments.
-template <class Class, typename MethodPtr>
-PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
-    Class* obj_ptr, MethodPtr method_ptr) {
-  return MakePolymorphicAction(
-      internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
-}
-
-// WithoutArgs(inner_action) can be used in a mock function with a
-// non-empty argument list to perform inner_action, which takes no
-// argument.  In other words, it adapts an action accepting no
-// argument to one that accepts (and ignores) arguments.
-template <typename InnerAction>
-inline internal::WithArgsAction<InnerAction>
-WithoutArgs(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction>(action);
-}
-
-// WithArg<k>(an_action) creates an action that passes the k-th
-// (0-based) argument of the mock function to an_action and performs
-// it.  It adapts an action accepting one argument to one that accepts
-// multiple arguments.  For convenience, we also provide
-// WithArgs<k>(an_action) (defined below) as a synonym.
-template <int k, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k>
-WithArg(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction, k>(action);
-}
-
 // The ACTION*() macros trigger warning C4100 (unreferenced formal
 // parameter) in MSVC with -W4.  Unfortunately they cannot be fixed in
 // the macro definition, as the warnings are generated when the macro
@@ -14809,7 +12999,7 @@
 ACTION_TEMPLATE(ReturnArg,
                 HAS_1_TEMPLATE_PARAMS(int, k),
                 AND_0_VALUE_PARAMS()) {
-  return ::testing::get<k>(args);
+  return ::std::get<k>(args);
 }
 
 // Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
@@ -14817,7 +13007,7 @@
 ACTION_TEMPLATE(SaveArg,
                 HAS_1_TEMPLATE_PARAMS(int, k),
                 AND_1_VALUE_PARAMS(pointer)) {
-  *pointer = ::testing::get<k>(args);
+  *pointer = ::std::get<k>(args);
 }
 
 // Action SaveArgPointee<k>(pointer) saves the value pointed to
@@ -14825,7 +13015,7 @@
 ACTION_TEMPLATE(SaveArgPointee,
                 HAS_1_TEMPLATE_PARAMS(int, k),
                 AND_1_VALUE_PARAMS(pointer)) {
-  *pointer = *::testing::get<k>(args);
+  *pointer = *::std::get<k>(args);
 }
 
 // Action SetArgReferee<k>(value) assigns 'value' to the variable
@@ -14833,13 +13023,13 @@
 ACTION_TEMPLATE(SetArgReferee,
                 HAS_1_TEMPLATE_PARAMS(int, k),
                 AND_1_VALUE_PARAMS(value)) {
-  typedef typename ::testing::tuple_element<k, args_type>::type argk_type;
+  typedef typename ::std::tuple_element<k, args_type>::type argk_type;
   // Ensures that argument #k is a reference.  If you get a compiler
   // error on the next line, you are using SetArgReferee<k>(value) in
   // a mock function whose k-th (0-based) argument is not a reference.
   GTEST_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
                         SetArgReferee_must_be_used_with_a_reference_argument);
-  ::testing::get<k>(args) = value;
+  ::std::get<k>(args) = value;
 }
 
 // Action SetArrayArgument<k>(first, last) copies the elements in
@@ -14852,9 +13042,9 @@
                 AND_2_VALUE_PARAMS(first, last)) {
   // Visual Studio deprecates ::std::copy, so we use our own copy in that case.
 #ifdef _MSC_VER
-  internal::CopyElements(first, last, ::testing::get<k>(args));
+  internal::CopyElements(first, last, ::std::get<k>(args));
 #else
-  ::std::copy(first, last, ::testing::get<k>(args));
+  ::std::copy(first, last, ::std::get<k>(args));
 #endif
 }
 
@@ -14863,7 +13053,7 @@
 ACTION_TEMPLATE(DeleteArg,
                 HAS_1_TEMPLATE_PARAMS(int, k),
                 AND_0_VALUE_PARAMS()) {
-  delete ::testing::get<k>(args);
+  delete ::std::get<k>(args);
 }
 
 // This action returns the value pointed to by 'pointer'.
@@ -14920,8 +13110,7 @@
 // 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: marcus.boerger@google.com (Marcus Boerger)
+
 
 // Google Mock - a framework for writing C++ mock classes.
 //
@@ -14930,12 +13119,26 @@
 // Note that tests are implemented in gmock-matchers_test.cc rather than
 // gmock-more-matchers-test.cc.
 
-#ifndef GMOCK_GMOCK_MORE_MATCHERS_H_
-#define GMOCK_GMOCK_MORE_MATCHERS_H_
+// GOOGLETEST_CM0002 DO NOT DELETE
+
+#ifndef GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
+#define GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
 
 
 namespace testing {
 
+// Silence C4100 (unreferenced formal
+// parameter) for MSVC
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable:4100)
+#if (_MSC_VER == 1900)
+// and silence C4800 (C4800: 'int *const ': forcing value
+// to bool 'true' or 'false') for MSVC 14
+# pragma warning(disable:4800)
+  #endif
+#endif
+
 // Defines a matcher that matches an empty container. The container must
 // support both size() and empty(), which all STL-like containers provide.
 MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") {
@@ -14946,15 +13149,250 @@
   return false;
 }
 
+// Define a matcher that matches a value that evaluates in boolean
+// context to true.  Useful for types that define "explicit operator
+// bool" operators and so can't be compared for equality with true
+// and false.
+MATCHER(IsTrue, negation ? "is false" : "is true") {
+  return static_cast<bool>(arg);
+}
+
+// Define a matcher that matches a value that evaluates in boolean
+// context to false.  Useful for types that define "explicit operator
+// bool" operators and so can't be compared for equality with true
+// and false.
+MATCHER(IsFalse, negation ? "is true" : "is false") {
+  return !static_cast<bool>(arg);
+}
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+
 }  // namespace testing
 
-#endif  // GMOCK_GMOCK_MORE_MATCHERS_H_
+#endif  // GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
+// Copyright 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.
+
+
+// Implements class templates NiceMock, NaggyMock, and StrictMock.
+//
+// Given a mock class MockFoo that is created using Google Mock,
+// NiceMock<MockFoo> is a subclass of MockFoo that allows
+// uninteresting calls (i.e. calls to mock methods that have no
+// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
+// that prints a warning when an uninteresting call occurs, and
+// StrictMock<MockFoo> is a subclass of MockFoo that treats all
+// uninteresting calls as errors.
+//
+// Currently a mock is naggy by default, so MockFoo and
+// NaggyMock<MockFoo> behave like the same.  However, we will soon
+// switch the default behavior of mocks to be nice, as that in general
+// leads to more maintainable tests.  When that happens, MockFoo will
+// stop behaving like NaggyMock<MockFoo> and start behaving like
+// NiceMock<MockFoo>.
+//
+// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
+// their respective base class.  Therefore you can write
+// NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo
+// has a constructor that accepts (int, const char*), for example.
+//
+// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
+// and StrictMock<MockFoo> only works for mock methods defined using
+// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
+// If a mock method is defined in a base class of MockFoo, the "nice"
+// or "strict" modifier may not affect it, depending on the compiler.
+// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
+// supported.
+
+// GOOGLETEST_CM0002 DO NOT DELETE
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
+
+
+namespace testing {
+
+template <class MockClass>
+class NiceMock : public MockClass {
+ public:
+  NiceMock() : MockClass() {
+    ::testing::Mock::AllowUninterestingCalls(
+        internal::ImplicitCast_<MockClass*>(this));
+  }
+
+  // Ideally, we would inherit base class's constructors through a using
+  // declaration, which would preserve their visibility. However, many existing
+  // tests rely on the fact that current implementation reexports protected
+  // constructors as public. These tests would need to be cleaned up first.
+
+  // Single argument constructor is special-cased so that it can be
+  // made explicit.
+  template <typename A>
+  explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
+    ::testing::Mock::AllowUninterestingCalls(
+        internal::ImplicitCast_<MockClass*>(this));
+  }
+
+  template <typename A1, typename A2, typename... An>
+  NiceMock(A1&& arg1, A2&& arg2, An&&... args)
+      : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
+                  std::forward<An>(args)...) {
+    ::testing::Mock::AllowUninterestingCalls(
+        internal::ImplicitCast_<MockClass*>(this));
+  }
+
+  ~NiceMock() {  // NOLINT
+    ::testing::Mock::UnregisterCallReaction(
+        internal::ImplicitCast_<MockClass*>(this));
+  }
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock);
+};
+
+template <class MockClass>
+class NaggyMock : public MockClass {
+ public:
+  NaggyMock() : MockClass() {
+    ::testing::Mock::WarnUninterestingCalls(
+        internal::ImplicitCast_<MockClass*>(this));
+  }
+
+  // Ideally, we would inherit base class's constructors through a using
+  // declaration, which would preserve their visibility. However, many existing
+  // tests rely on the fact that current implementation reexports protected
+  // constructors as public. These tests would need to be cleaned up first.
+
+  // Single argument constructor is special-cased so that it can be
+  // made explicit.
+  template <typename A>
+  explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
+    ::testing::Mock::WarnUninterestingCalls(
+        internal::ImplicitCast_<MockClass*>(this));
+  }
+
+  template <typename A1, typename A2, typename... An>
+  NaggyMock(A1&& arg1, A2&& arg2, An&&... args)
+      : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
+                  std::forward<An>(args)...) {
+    ::testing::Mock::WarnUninterestingCalls(
+        internal::ImplicitCast_<MockClass*>(this));
+  }
+
+  ~NaggyMock() {  // NOLINT
+    ::testing::Mock::UnregisterCallReaction(
+        internal::ImplicitCast_<MockClass*>(this));
+  }
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock);
+};
+
+template <class MockClass>
+class StrictMock : public MockClass {
+ public:
+  StrictMock() : MockClass() {
+    ::testing::Mock::FailUninterestingCalls(
+        internal::ImplicitCast_<MockClass*>(this));
+  }
+
+  // Ideally, we would inherit base class's constructors through a using
+  // declaration, which would preserve their visibility. However, many existing
+  // tests rely on the fact that current implementation reexports protected
+  // constructors as public. These tests would need to be cleaned up first.
+
+  // Single argument constructor is special-cased so that it can be
+  // made explicit.
+  template <typename A>
+  explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
+    ::testing::Mock::FailUninterestingCalls(
+        internal::ImplicitCast_<MockClass*>(this));
+  }
+
+  template <typename A1, typename A2, typename... An>
+  StrictMock(A1&& arg1, A2&& arg2, An&&... args)
+      : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
+                  std::forward<An>(args)...) {
+    ::testing::Mock::FailUninterestingCalls(
+        internal::ImplicitCast_<MockClass*>(this));
+  }
+
+  ~StrictMock() {  // NOLINT
+    ::testing::Mock::UnregisterCallReaction(
+        internal::ImplicitCast_<MockClass*>(this));
+  }
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
+};
+
+// The following specializations catch some (relatively more common)
+// user errors of nesting nice and strict mocks.  They do NOT catch
+// all possible errors.
+
+// These specializations are declared but not defined, as NiceMock,
+// NaggyMock, and StrictMock cannot be nested.
+
+template <typename MockClass>
+class NiceMock<NiceMock<MockClass> >;
+template <typename MockClass>
+class NiceMock<NaggyMock<MockClass> >;
+template <typename MockClass>
+class NiceMock<StrictMock<MockClass> >;
+
+template <typename MockClass>
+class NaggyMock<NiceMock<MockClass> >;
+template <typename MockClass>
+class NaggyMock<NaggyMock<MockClass> >;
+template <typename MockClass>
+class NaggyMock<StrictMock<MockClass> >;
+
+template <typename MockClass>
+class StrictMock<NiceMock<MockClass> >;
+template <typename MockClass>
+class StrictMock<NaggyMock<MockClass> >;
+template <typename MockClass>
+class StrictMock<StrictMock<MockClass> >;
+
+}  // namespace testing
+
+#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
 
 namespace testing {
 
 // Declares Google Mock flags that we want a user to use programmatically.
 GMOCK_DECLARE_bool_(catch_leaked_mocks);
 GMOCK_DECLARE_string_(verbose);
+GMOCK_DECLARE_int32_(default_mock_behavior);
 
 // Initializes Google Mock.  This must be called before running the
 // tests.  In particular, it parses the command line for the flags
@@ -14973,6 +13411,10 @@
 // UNICODE mode.
 GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv);
 
+// This overloaded version can be used on Arduino/embedded platforms where
+// there is no argc/argv.
+GTEST_API_ void InitGoogleMock();
+
 }  // namespace testing
 
 #endif  // GMOCK_INCLUDE_GMOCK_GMOCK_H_
diff --git a/internal/ceres/gmock_gtest_all.cc b/internal/ceres/gmock_gtest_all.cc
index b3d980b..dd43444 100644
--- a/internal/ceres/gmock_gtest_all.cc
+++ b/internal/ceres/gmock_gtest_all.cc
@@ -26,10 +26,9 @@
 // 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: mheule@google.com (Markus Heule)
-//
-// Google C++ Testing Framework (Google Test)
+// Google C++ Testing and Mocking Framework (Google Test)
 //
 // Sometimes it's desirable to build Google Test by compiling a single file.
 // This file serves this purpose.
@@ -67,10 +66,9 @@
 // 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: wan@google.com (Zhanyong Wan)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
 
 // Copyright 2007, Google Inc.
 // All rights reserved.
@@ -100,16 +98,20 @@
 // 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: wan@google.com (Zhanyong Wan)
+
 //
 // Utilities for testing Google Test itself and code that uses Google Test
 // (e.g. frameworks built on top of Google Test).
 
+// GOOGLETEST_CM0004 DO NOT DELETE
+
 #ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
 #define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
 
 
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
 namespace testing {
 
 // This helper class can be used to mock out Google Test failure reporting
@@ -141,14 +143,15 @@
                                    TestPartResultArray* result);
 
   // The d'tor restores the previous test part result reporter.
-  virtual ~ScopedFakeTestPartResultReporter();
+  ~ScopedFakeTestPartResultReporter() override;
 
   // Appends the TestPartResult object to the TestPartResultArray
   // received in the constructor.
   //
   // This method is from the TestPartResultReporterInterface
   // interface.
-  virtual void ReportTestPartResult(const TestPartResult& result);
+  void ReportTestPartResult(const TestPartResult& result) override;
+
  private:
   void Init();
 
@@ -170,13 +173,12 @@
  public:
   // The constructor remembers the arguments.
   SingleFailureChecker(const TestPartResultArray* results,
-                       TestPartResult::Type type,
-                       const string& substr);
+                       TestPartResult::Type type, const std::string& substr);
   ~SingleFailureChecker();
  private:
   const TestPartResultArray* const results_;
   const TestPartResult::Type type_;
-  const string substr_;
+  const std::string substr_;
 
   GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
 };
@@ -185,6 +187,8 @@
 
 }  // namespace testing
 
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251
+
 // A set of macros for testing Google Test assertions or code that's expected
 // to generate Google Test fatal failures.  It verifies that the given
 // statement will cause exactly one fatal Google Test failure with 'substr'
@@ -324,8 +328,6 @@
 
 #if GTEST_OS_LINUX
 
-// TODO(kenton@google.com): Use autoconf to detect availability of
-// gettimeofday().
 # define GTEST_HAS_GETTIMEOFDAY_ 1
 
 # include <fcntl.h>  // NOLINT
@@ -338,10 +340,6 @@
 # include <unistd.h>  // NOLINT
 # include <string>
 
-#elif GTEST_OS_SYMBIAN
-# define GTEST_HAS_GETTIMEOFDAY_ 1
-# include <sys/time.h>  // NOLINT
-
 #elif GTEST_OS_ZOS
 # define GTEST_HAS_GETTIMEOFDAY_ 1
 # include <sys/time.h>  // NOLINT
@@ -363,11 +361,6 @@
 
 # if GTEST_OS_WINDOWS_MINGW
 // MinGW has gettimeofday() but not _ftime64().
-// TODO(kenton@google.com): Use autoconf to detect availability of
-//   gettimeofday().
-// TODO(kenton@google.com): There are other ways to get the time on
-//   Windows, like GetTickCount() or GetSystemTimeAsFileTime().  MinGW
-//   supports these.  consider using them instead.
 #  define GTEST_HAS_GETTIMEOFDAY_ 1
 #  include <sys/time.h>  // NOLINT
 # endif  // GTEST_OS_WINDOWS_MINGW
@@ -380,8 +373,6 @@
 #else
 
 // Assume other platforms have gettimeofday().
-// TODO(kenton@google.com): Use autoconf to detect availability of
-//   gettimeofday().
 # define GTEST_HAS_GETTIMEOFDAY_ 1
 
 // cpplint thinks that the header is already included, so we want to
@@ -402,12 +393,6 @@
 # include <sys/types.h>  // NOLINT
 #endif
 
-// Indicates that this translation unit is part of Google Test's
-// implementation.  It must come before gtest-internal-inl.h is
-// included, or there will be a compiler error.  This trick is to
-// prevent a user from accidentally including gtest-internal-inl.h in
-// his code.
-#define GTEST_IMPLEMENTATION_ 1
 // Copyright 2005, Google Inc.
 // All rights reserved.
 //
@@ -437,24 +422,13 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Utility functions and classes used by the Google C++ testing framework.
-//
-// Author: wan@google.com (Zhanyong Wan)
-//
+// Utility functions and classes used by the Google C++ testing framework.//
 // This file contains purely Google Test's internal implementation.  Please
 // DO NOT #INCLUDE IT IN A USER PROGRAM.
 
 #ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_
 #define GTEST_SRC_GTEST_INTERNAL_INL_H_
 
-// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is
-// part of Google Test's implementation; otherwise it's undefined.
-#if !GTEST_IMPLEMENTATION_
-// If this file is included from the user's code, just say no.
-# error "gtest-internal-inl.h is part of Google Test's internal implementation."
-# error "It must not be included except by Google Test itself."
-#endif  // GTEST_IMPLEMENTATION_
-
 #ifndef _WIN32_WCE
 # include <errno.h>
 #endif  // !_WIN32_WCE
@@ -463,6 +437,7 @@
 #include <string.h>  // For memmove.
 
 #include <algorithm>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -477,6 +452,9 @@
 #endif  // GTEST_OS_WINDOWS
 
 
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
 namespace testing {
 
 // Declares the flags.
@@ -501,6 +479,7 @@
 const char kListTestsFlag[] = "list_tests";
 const char kOutputFlag[] = "output";
 const char kPrintTimeFlag[] = "print_time";
+const char kPrintUTF8Flag[] = "print_utf8";
 const char kRandomSeedFlag[] = "random_seed";
 const char kRepeatFlag[] = "repeat";
 const char kShuffleFlag[] = "shuffle";
@@ -581,6 +560,7 @@
     list_tests_ = GTEST_FLAG(list_tests);
     output_ = GTEST_FLAG(output);
     print_time_ = GTEST_FLAG(print_time);
+    print_utf8_ = GTEST_FLAG(print_utf8);
     random_seed_ = GTEST_FLAG(random_seed);
     repeat_ = GTEST_FLAG(repeat);
     shuffle_ = GTEST_FLAG(shuffle);
@@ -602,6 +582,7 @@
     GTEST_FLAG(list_tests) = list_tests_;
     GTEST_FLAG(output) = output_;
     GTEST_FLAG(print_time) = print_time_;
+    GTEST_FLAG(print_utf8) = print_utf8_;
     GTEST_FLAG(random_seed) = random_seed_;
     GTEST_FLAG(repeat) = repeat_;
     GTEST_FLAG(shuffle) = shuffle_;
@@ -623,6 +604,7 @@
   bool list_tests_;
   std::string output_;
   bool print_time_;
+  bool print_utf8_;
   internal::Int32 random_seed_;
   internal::Int32 repeat_;
   bool shuffle_;
@@ -641,7 +623,7 @@
 
 // Converts a wide string to a narrow string in UTF-8 encoding.
 // The wide string is assumed to have the following encoding:
-//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin)
 //   UTF-32 if sizeof(wchar_t) == 4 (on Linux)
 // Parameter str points to a null-terminated wide string.
 // Parameter num_chars may additionally limit the number
@@ -798,10 +780,10 @@
   // works well enough for matching test names, which are short.
   static bool PatternMatchesString(const char *pattern, const char *str);
 
-  // Returns true iff the user-specified filter matches the test case
+  // Returns true iff the user-specified filter matches the test suite
   // name and the test name.
-  static bool FilterMatchesTest(const std::string &test_case_name,
-                                const std::string &test_name);
+  static bool FilterMatchesTest(const std::string& test_suite_name,
+                                const std::string& test_name);
 
 #if GTEST_OS_WINDOWS
   // Function for supporting the gtest_catch_exception flag.
@@ -833,7 +815,7 @@
   //                in the trace.
   //   skip_count - the number of top frames to be skipped; doesn't count
   //                against max_depth.
-  virtual string CurrentStackTrace(int max_depth, int skip_count) = 0;
+  virtual std::string CurrentStackTrace(int max_depth, int skip_count) = 0;
 
   // UponLeavingGTest() should be called immediately before Google Test calls
   // user code. It saves some information about the current stack that
@@ -853,10 +835,20 @@
  public:
   OsStackTraceGetter() {}
 
-  virtual string CurrentStackTrace(int max_depth, int skip_count);
-  virtual void UponLeavingGTest();
+  std::string CurrentStackTrace(int max_depth, int skip_count) override;
+  void UponLeavingGTest() override;
 
  private:
+#if GTEST_HAS_ABSL
+  Mutex mutex_;  // Protects all internal state.
+
+  // We save the stack frame below the frame that calls user code.
+  // We do this because the address of the frame immediately below
+  // the user code changes between the call to UponLeavingGTest()
+  // and any calls to the stack trace code from within the user code.
+  void* caller_frame_ = nullptr;
+#endif  // GTEST_HAS_ABSL
+
   GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter);
 };
 
@@ -875,7 +867,7 @@
   explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);
   // Implements the TestPartResultReporterInterface. Reports the test part
   // result in the current test.
-  virtual void ReportTestPartResult(const TestPartResult& result);
+  void ReportTestPartResult(const TestPartResult& result) override;
 
  private:
   UnitTestImpl* const unit_test_;
@@ -891,7 +883,7 @@
   explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);
   // Implements the TestPartResultReporterInterface. The implementation just
   // delegates to the current global test part result reporter of *unit_test_.
-  virtual void ReportTestPartResult(const TestPartResult& result);
+  void ReportTestPartResult(const TestPartResult& result) override;
 
  private:
   UnitTestImpl* const unit_test_;
@@ -929,22 +921,25 @@
   void SetTestPartResultReporterForCurrentThread(
       TestPartResultReporterInterface* reporter);
 
-  // Gets the number of successful test cases.
-  int successful_test_case_count() const;
+  // Gets the number of successful test suites.
+  int successful_test_suite_count() const;
 
-  // Gets the number of failed test cases.
-  int failed_test_case_count() const;
+  // Gets the number of failed test suites.
+  int failed_test_suite_count() const;
 
-  // Gets the number of all test cases.
-  int total_test_case_count() const;
+  // Gets the number of all test suites.
+  int total_test_suite_count() const;
 
-  // Gets the number of all test cases that contain at least one test
+  // Gets the number of all test suites that contain at least one test
   // that should run.
-  int test_case_to_run_count() const;
+  int test_suite_to_run_count() const;
 
   // Gets the number of successful tests.
   int successful_test_count() const;
 
+  // Gets the number of skipped tests.
+  int skipped_test_count() const;
+
   // Gets the number of failed tests.
   int failed_test_count() const;
 
@@ -970,27 +965,32 @@
   // Gets the elapsed time, in milliseconds.
   TimeInMillis elapsed_time() const { return elapsed_time_; }
 
-  // Returns true iff the unit test passed (i.e. all test cases passed).
+  // Returns true iff the unit test passed (i.e. all test suites passed).
   bool Passed() const { return !Failed(); }
 
-  // Returns true iff the unit test failed (i.e. some test case failed
+  // Returns true iff the unit test failed (i.e. some test suite failed
   // or something outside of all tests failed).
   bool Failed() const {
-    return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed();
+    return failed_test_suite_count() > 0 || ad_hoc_test_result()->Failed();
   }
 
-  // Gets the i-th test case among all the test cases. i can range from 0 to
-  // total_test_case_count() - 1. If i is not in that range, returns NULL.
-  const TestCase* GetTestCase(int i) const {
-    const int index = GetElementOr(test_case_indices_, i, -1);
-    return index < 0 ? NULL : test_cases_[i];
+  // Gets the i-th test suite among all the test suites. i can range from 0 to
+  // total_test_suite_count() - 1. If i is not in that range, returns NULL.
+  const TestSuite* GetTestSuite(int i) const {
+    const int index = GetElementOr(test_suite_indices_, i, -1);
+    return index < 0 ? nullptr : test_suites_[i];
   }
 
-  // Gets the i-th test case among all the test cases. i can range from 0 to
-  // total_test_case_count() - 1. If i is not in that range, returns NULL.
-  TestCase* GetMutableTestCase(int i) {
-    const int index = GetElementOr(test_case_indices_, i, -1);
-    return index < 0 ? NULL : test_cases_[index];
+  //  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+  const TestCase* GetTestCase(int i) const { return GetTestSuite(i); }
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
+  // Gets the i-th test suite among all the test suites. i can range from 0 to
+  // total_test_suite_count() - 1. If i is not in that range, returns NULL.
+  TestSuite* GetMutableSuiteCase(int i) {
+    const int index = GetElementOr(test_suite_indices_, i, -1);
+    return index < 0 ? nullptr : test_suites_[index];
   }
 
   // Provides access to the event listener list.
@@ -1027,30 +1027,38 @@
   // trace but Bar() and CurrentOsStackTraceExceptTop() won't.
   std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_;
 
-  // Finds and returns a TestCase with the given name.  If one doesn't
+  // Finds and returns a TestSuite with the given name.  If one doesn't
   // exist, creates one and returns it.
   //
   // Arguments:
   //
-  //   test_case_name: name of the test case
+  //   test_suite_name: name of the test suite
   //   type_param:     the name of the test's type parameter, or NULL if
   //                   this is not a typed or a type-parameterized test.
-  //   set_up_tc:      pointer to the function that sets up the test case
-  //   tear_down_tc:   pointer to the function that tears down the test case
-  TestCase* GetTestCase(const char* test_case_name,
-                        const char* type_param,
-                        Test::SetUpTestCaseFunc set_up_tc,
-                        Test::TearDownTestCaseFunc tear_down_tc);
+  //   set_up_tc:      pointer to the function that sets up the test suite
+  //   tear_down_tc:   pointer to the function that tears down the test suite
+  TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param,
+                          internal::SetUpTestSuiteFunc set_up_tc,
+                          internal::TearDownTestSuiteFunc tear_down_tc);
+
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+  TestCase* GetTestCase(const char* test_case_name, const char* type_param,
+                        internal::SetUpTestSuiteFunc set_up_tc,
+                        internal::TearDownTestSuiteFunc tear_down_tc) {
+    return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc);
+  }
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
   // Adds a TestInfo to the unit test.
   //
   // Arguments:
   //
-  //   set_up_tc:    pointer to the function that sets up the test case
-  //   tear_down_tc: pointer to the function that tears down the test case
+  //   set_up_tc:    pointer to the function that sets up the test suite
+  //   tear_down_tc: pointer to the function that tears down the test suite
   //   test_info:    the TestInfo object
-  void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,
-                   Test::TearDownTestCaseFunc tear_down_tc,
+  void AddTestInfo(internal::SetUpTestSuiteFunc set_up_tc,
+                   internal::TearDownTestSuiteFunc tear_down_tc,
                    TestInfo* test_info) {
     // In order to support thread-safe death tests, we need to
     // remember the original working directory when the test program
@@ -1065,23 +1073,20 @@
           << "Failed to get the current working directory.";
     }
 
-    GetTestCase(test_info->test_case_name(),
-                test_info->type_param(),
-                set_up_tc,
-                tear_down_tc)->AddTestInfo(test_info);
+    GetTestSuite(test_info->test_suite_name(), test_info->type_param(),
+                 set_up_tc, tear_down_tc)
+        ->AddTestInfo(test_info);
   }
 
-#if GTEST_HAS_PARAM_TEST
-  // Returns ParameterizedTestCaseRegistry object used to keep track of
+  // Returns ParameterizedTestSuiteRegistry object used to keep track of
   // value-parameterized tests and instantiate and register them.
-  internal::ParameterizedTestCaseRegistry& parameterized_test_registry() {
+  internal::ParameterizedTestSuiteRegistry& parameterized_test_registry() {
     return parameterized_test_registry_;
   }
-#endif  // GTEST_HAS_PARAM_TEST
 
-  // Sets the TestCase object for the test that's currently running.
-  void set_current_test_case(TestCase* a_current_test_case) {
-    current_test_case_ = a_current_test_case;
+  // Sets the TestSuite object for the test that's currently running.
+  void set_current_test_suite(TestSuite* a_current_test_suite) {
+    current_test_suite_ = a_current_test_suite;
   }
 
   // Sets the TestInfo object for the test that's currently running.  If
@@ -1092,7 +1097,7 @@
   }
 
   // Registers all parameterized tests defined using TEST_P and
-  // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter
+  // INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter
   // combination. This method can be called more then once; it has guards
   // protecting from registering the tests more then once.  If
   // value-parameterized tests are disabled, RegisterParameterizedTests is
@@ -1107,7 +1112,7 @@
 
   // Clears the results of all tests, except the ad hoc tests.
   void ClearNonAdHocTestResult() {
-    ForEach(test_cases_, TestCase::ClearTestCaseResult);
+    ForEach(test_suites_, TestSuite::ClearTestSuiteResult);
   }
 
   // Clears the results of ad-hoc test assertions.
@@ -1116,7 +1121,7 @@
   }
 
   // Adds a TestProperty to the current TestResult object when invoked in a
-  // context of a test or a test case, or to the global property set. If the
+  // context of a test or a test suite, or to the global property set. If the
   // result already contains a property with the same key, the value will be
   // updated.
   void RecordProperty(const TestProperty& test_property);
@@ -1128,7 +1133,7 @@
 
   // Matches the full name of each test against the user-specified
   // filter to decide whether the test should run, then records the
-  // result in each TestCase and TestInfo object.
+  // result in each TestSuite and TestInfo object.
   // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests
   // based on sharding variables in the environment.
   // Returns the number of tests that should run.
@@ -1137,7 +1142,7 @@
   // Prints the names of the tests matching the user-specified filter flag.
   void ListTestsMatchingFilter();
 
-  const TestCase* current_test_case() const { return current_test_case_; }
+  const TestSuite* current_test_suite() const { return current_test_suite_; }
   TestInfo* current_test_info() { return current_test_info_; }
   const TestInfo* current_test_info() const { return current_test_info_; }
 
@@ -1198,11 +1203,11 @@
   // Gets the random number generator.
   internal::Random* random() { return &random_; }
 
-  // Shuffles all test cases, and the tests within each test case,
+  // Shuffles all test suites, and the tests within each test suite,
   // making sure that death tests are still run first.
   void ShuffleTests();
 
-  // Restores the test cases and tests to their order before the first shuffle.
+  // Restores the test suites and tests to their order before the first shuffle.
   void UnshuffleTests();
 
   // Returns the value of GTEST_FLAG(catch_exceptions) at the moment
@@ -1242,33 +1247,31 @@
   // before/after the tests are run.
   std::vector<Environment*> environments_;
 
-  // The vector of TestCases in their original order.  It owns the
+  // The vector of TestSuites in their original order.  It owns the
   // elements in the vector.
-  std::vector<TestCase*> test_cases_;
+  std::vector<TestSuite*> test_suites_;
 
-  // Provides a level of indirection for the test case list to allow
-  // easy shuffling and restoring the test case order.  The i-th
-  // element of this vector is the index of the i-th test case in the
+  // Provides a level of indirection for the test suite list to allow
+  // easy shuffling and restoring the test suite order.  The i-th
+  // element of this vector is the index of the i-th test suite in the
   // shuffled order.
-  std::vector<int> test_case_indices_;
+  std::vector<int> test_suite_indices_;
 
-#if GTEST_HAS_PARAM_TEST
   // ParameterizedTestRegistry object used to register value-parameterized
   // tests.
-  internal::ParameterizedTestCaseRegistry parameterized_test_registry_;
+  internal::ParameterizedTestSuiteRegistry parameterized_test_registry_;
 
   // Indicates whether RegisterParameterizedTests() has been called already.
   bool parameterized_tests_registered_;
-#endif  // GTEST_HAS_PARAM_TEST
 
-  // Index of the last death test case registered.  Initially -1.
-  int last_death_test_case_;
+  // Index of the last death test suite registered.  Initially -1.
+  int last_death_test_suite_;
 
-  // This points to the TestCase for the currently running test.  It
-  // changes as Google Test goes through one test case after another.
+  // This points to the TestSuite for the currently running test.  It
+  // changes as Google Test goes through one test suite after another.
   // When no test is running, this is set to NULL and Google Test
   // stores assertion results in ad_hoc_test_result_.  Initially NULL.
-  TestCase* current_test_case_;
+  TestSuite* current_test_suite_;
 
   // This points to the TestInfo for the currently running test.  It
   // changes as Google Test goes through one test after another.  When
@@ -1315,8 +1318,8 @@
 #if GTEST_HAS_DEATH_TEST
   // The decomposed components of the gtest_internal_run_death_test flag,
   // parsed when RUN_ALL_TESTS is called.
-  internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;
-  internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_;
+  std::unique_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;
+  std::unique_ptr<internal::DeathTestFactory> death_test_factory_;
 #endif  // GTEST_HAS_DEATH_TEST
 
   // A per-thread stack of traces created by the SCOPED_TRACE() macro.
@@ -1399,8 +1402,6 @@
 
   const bool parse_success = *end == '\0' && errno == 0;
 
-  // TODO(vladl@google.com): Convert this to compile time assertion when it is
-  // available.
   GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));
 
   const Integer result = static_cast<Integer>(parsed);
@@ -1439,7 +1440,7 @@
 #if GTEST_CAN_STREAM_RESULTS_
 
 // Streams test results to the given port on the given host machine.
-class GTEST_API_ StreamingListener : public EmptyTestEventListener {
+class StreamingListener : public EmptyTestEventListener {
  public:
   // Abstract base class for writing strings to a socket.
   class AbstractSocketWriter {
@@ -1447,32 +1448,30 @@
     virtual ~AbstractSocketWriter() {}
 
     // Sends a string to the socket.
-    virtual void Send(const string& message) = 0;
+    virtual void Send(const std::string& message) = 0;
 
     // Closes the socket.
     virtual void CloseConnection() {}
 
     // Sends a string and a newline to the socket.
-    void SendLn(const string& message) {
-      Send(message + "\n");
-    }
+    void SendLn(const std::string& message) { Send(message + "\n"); }
   };
 
   // Concrete class for actually writing strings to a socket.
   class SocketWriter : public AbstractSocketWriter {
    public:
-    SocketWriter(const string& host, const string& port)
+    SocketWriter(const std::string& host, const std::string& port)
         : sockfd_(-1), host_name_(host), port_num_(port) {
       MakeConnection();
     }
 
-    virtual ~SocketWriter() {
+    ~SocketWriter() override {
       if (sockfd_ != -1)
         CloseConnection();
     }
 
     // Sends a string to the socket.
-    virtual void Send(const string& message) {
+    void Send(const std::string& message) override {
       GTEST_CHECK_(sockfd_ != -1)
           << "Send() can be called only when there is a connection.";
 
@@ -1489,7 +1488,7 @@
     void MakeConnection();
 
     // Closes the socket.
-    void CloseConnection() {
+    void CloseConnection() override {
       GTEST_CHECK_(sockfd_ != -1)
           << "CloseConnection() can be called only when there is a connection.";
 
@@ -1498,26 +1497,28 @@
     }
 
     int sockfd_;  // socket file descriptor
-    const string host_name_;
-    const string port_num_;
+    const std::string host_name_;
+    const std::string port_num_;
 
     GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter);
   };  // class SocketWriter
 
   // Escapes '=', '&', '%', and '\n' characters in str as "%xx".
-  static string UrlEncode(const char* str);
+  static std::string UrlEncode(const char* str);
 
-  StreamingListener(const string& host, const string& port)
-      : socket_writer_(new SocketWriter(host, port)) { Start(); }
+  StreamingListener(const std::string& host, const std::string& port)
+      : socket_writer_(new SocketWriter(host, port)) {
+    Start();
+  }
 
   explicit StreamingListener(AbstractSocketWriter* socket_writer)
       : socket_writer_(socket_writer) { Start(); }
 
-  void OnTestProgramStart(const UnitTest& /* unit_test */) {
+  void OnTestProgramStart(const UnitTest& /* unit_test */) override {
     SendLn("event=TestProgramStart");
   }
 
-  void OnTestProgramEnd(const UnitTest& unit_test) {
+  void OnTestProgramEnd(const UnitTest& unit_test) override {
     // Note that Google Test current only report elapsed time for each
     // test iteration, not for the entire test program.
     SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed()));
@@ -1526,42 +1527,47 @@
     socket_writer_->CloseConnection();
   }
 
-  void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) {
+  void OnTestIterationStart(const UnitTest& /* unit_test */,
+                            int iteration) override {
     SendLn("event=TestIterationStart&iteration=" +
            StreamableToString(iteration));
   }
 
-  void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) {
+  void OnTestIterationEnd(const UnitTest& unit_test,
+                          int /* iteration */) override {
     SendLn("event=TestIterationEnd&passed=" +
            FormatBool(unit_test.Passed()) + "&elapsed_time=" +
            StreamableToString(unit_test.elapsed_time()) + "ms");
   }
 
-  void OnTestCaseStart(const TestCase& test_case) {
+  // Note that "event=TestCaseStart" is a wire format and has to remain
+  // "case" for compatibilty
+  void OnTestCaseStart(const TestCase& test_case) override {
     SendLn(std::string("event=TestCaseStart&name=") + test_case.name());
   }
 
-  void OnTestCaseEnd(const TestCase& test_case) {
-    SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed())
-           + "&elapsed_time=" + StreamableToString(test_case.elapsed_time())
-           + "ms");
+  // Note that "event=TestCaseEnd" is a wire format and has to remain
+  // "case" for compatibilty
+  void OnTestCaseEnd(const TestCase& test_case) override {
+    SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) +
+           "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) +
+           "ms");
   }
 
-  void OnTestStart(const TestInfo& test_info) {
+  void OnTestStart(const TestInfo& test_info) override {
     SendLn(std::string("event=TestStart&name=") + test_info.name());
   }
 
-  void OnTestEnd(const TestInfo& test_info) {
+  void OnTestEnd(const TestInfo& test_info) override {
     SendLn("event=TestEnd&passed=" +
            FormatBool((test_info.result())->Passed()) +
            "&elapsed_time=" +
            StreamableToString((test_info.result())->elapsed_time()) + "ms");
   }
 
-  void OnTestPartResult(const TestPartResult& test_part_result) {
+  void OnTestPartResult(const TestPartResult& test_part_result) override {
     const char* file_name = test_part_result.file_name();
-    if (file_name == NULL)
-      file_name = "";
+    if (file_name == nullptr) file_name = "";
     SendLn("event=TestPartResult&file=" + UrlEncode(file_name) +
            "&line=" + StreamableToString(test_part_result.line_number()) +
            "&message=" + UrlEncode(test_part_result.message()));
@@ -1569,15 +1575,15 @@
 
  private:
   // Sends the given message and a newline to the socket.
-  void SendLn(const string& message) { socket_writer_->SendLn(message); }
+  void SendLn(const std::string& message) { socket_writer_->SendLn(message); }
 
   // Called at the start of streaming to notify the receiver what
   // protocol we are using.
   void Start() { SendLn("gtest_streaming_protocol_version=1.0"); }
 
-  string FormatBool(bool value) { return value ? "1" : "0"; }
+  std::string FormatBool(bool value) { return value ? "1" : "0"; }
 
-  const scoped_ptr<AbstractSocketWriter> socket_writer_;
+  const std::unique_ptr<AbstractSocketWriter> socket_writer_;
 
   GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener);
 };  // class StreamingListener
@@ -1587,13 +1593,27 @@
 }  // namespace internal
 }  // namespace testing
 
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251
+
 #endif  // GTEST_SRC_GTEST_INTERNAL_INL_H_
-#undef GTEST_IMPLEMENTATION_
 
 #if GTEST_OS_WINDOWS
 # define vsnprintf _vsnprintf
 #endif  // GTEST_OS_WINDOWS
 
+#if GTEST_OS_MAC
+#ifndef GTEST_OS_IOS
+#include <crt_externs.h>
+#endif
+#endif
+
+#if GTEST_HAS_ABSL
+#include "absl/debugging/failure_signal_handler.h"
+#include "absl/debugging/stacktrace.h"
+#include "absl/debugging/symbolize.h"
+#include "absl/strings/str_cat.h"
+#endif  // GTEST_HAS_ABSL
+
 namespace testing {
 
 using internal::CountIf;
@@ -1603,20 +1623,22 @@
 
 // Constants.
 
-// A test whose test case name or test name matches this filter is
+// A test whose test suite name or test name matches this filter is
 // disabled and not run.
 static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*";
 
-// A test case whose name matches this filter is considered a death
-// test case and will be run before test cases whose name doesn't
+// A test suite whose name matches this filter is considered a death
+// test suite and will be run before test suites whose name doesn't
 // match this filter.
-static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
+static const char kDeathTestSuiteFilter[] = "*DeathTest:*DeathTest/*";
 
 // A test filter that matches everything.
 static const char kUniversalFilter[] = "*";
 
-// The default output file for XML output.
-static const char kDefaultOutputFile[] = "test_detail.xml";
+// The default output format.
+static const char kDefaultOutputFormat[] = "xml";
+// The default output file.
+static const char kDefaultOutputFile[] = "test_detail";
 
 // The environment variable name for the test shard index.
 static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
@@ -1635,15 +1657,31 @@
 // specified on the command line.
 bool g_help_flag = false;
 
+// Utilty function to Open File for Writing
+static FILE* OpenFileForWriting(const std::string& output_file) {
+  FILE* fileout = nullptr;
+  FilePath output_file_path(output_file);
+  FilePath output_dir(output_file_path.RemoveFileName());
+
+  if (output_dir.CreateDirectoriesRecursively()) {
+    fileout = posix::FOpen(output_file.c_str(), "w");
+  }
+  if (fileout == nullptr) {
+    GTEST_LOG_(FATAL) << "Unable to open file \"" << output_file << "\"";
+  }
+  return fileout;
+}
+
 }  // namespace internal
 
+// Bazel passes in the argument to '--test_filter' via the TESTBRIDGE_TEST_ONLY
+// environment variable.
 static const char* GetDefaultFilter() {
-#ifdef GTEST_TEST_FILTER_ENV_VAR_
-  const char* const testbridge_test_only = getenv(GTEST_TEST_FILTER_ENV_VAR_);
-  if (testbridge_test_only != NULL) {
+  const char* const testbridge_test_only =
+      internal::posix::GetEnv("TESTBRIDGE_TEST_ONLY");
+  if (testbridge_test_only != nullptr) {
     return testbridge_test_only;
   }
-#endif  // GTEST_TEST_FILTER_ENV_VAR_
   return kUniversalFilter;
 }
 
@@ -1680,15 +1718,28 @@
     "exclude).  A test is run if it matches one of the positive "
     "patterns and does not match any of the negative patterns.");
 
+GTEST_DEFINE_bool_(
+    install_failure_signal_handler,
+    internal::BoolFromGTestEnv("install_failure_signal_handler", false),
+    "If true and supported on the current platform, " GTEST_NAME_ " should "
+    "install a signal handler that dumps debugging information when fatal "
+    "signals are raised.");
+
 GTEST_DEFINE_bool_(list_tests, false,
                    "List all tests without running them.");
 
+// The net priority order after flag processing is thus:
+//   --gtest_output command line flag
+//   GTEST_OUTPUT environment variable
+//   XML_OUTPUT_FILE environment variable
+//   ''
 GTEST_DEFINE_string_(
     output,
-    internal::StringFromGTestEnv("output", ""),
-    "A format (currently must be \"xml\"), optionally followed "
-    "by a colon and an output file name or directory. A directory "
-    "is indicated by a trailing pathname separator. "
+    internal::StringFromGTestEnv("output",
+      internal::OutputFlagAlsoCheckEnvVar().c_str()),
+    "A format (defaults to \"xml\" but can be specified to be \"json\"), "
+    "optionally followed by a colon and an output file name or directory. "
+    "A directory is indicated by a trailing pathname separator. "
     "Examples: \"xml:filename.xml\", \"xml::directoryname/\". "
     "If a directory is specified, output files will be created "
     "within that directory, with file-names based on the test "
@@ -1701,6 +1752,12 @@
     "True iff " GTEST_NAME_
     " should display elapsed time in text output.");
 
+GTEST_DEFINE_bool_(
+    print_utf8,
+    internal::BoolFromGTestEnv("print_utf8", true),
+    "True iff " GTEST_NAME_
+    " prints UTF8 characters as text.");
+
 GTEST_DEFINE_int32_(
     random_seed,
     internal::Int32FromGTestEnv("random_seed", 0),
@@ -1742,7 +1799,7 @@
     internal::BoolFromGTestEnv("throw_on_failure", false),
     "When this flag is specified, a failed assertion will throw an exception "
     "if exceptions are enabled or exit the program with a non-zero code "
-    "otherwise.");
+    "otherwise. For use with an external test framework.");
 
 #if GTEST_USE_OWN_FLAGFILE_FLAG_
 GTEST_DEFINE_string_(
@@ -1758,7 +1815,8 @@
 // than kMaxRange.
 UInt32 Random::Generate(UInt32 range) {
   // These constants are the same as are used in glibc's rand(3).
-  state_ = (1103515245U*state_ + 12345U) % kMaxRange;
+  // Use wider types than necessary to prevent unsigned overflow diagnostics.
+  state_ = static_cast<UInt32>(1103515245ULL*state_ + 12345U) % kMaxRange;
 
   GTEST_CHECK_(range > 0)
       << "Cannot generate a number in the range [0, 0).";
@@ -1777,11 +1835,11 @@
 // Google Test before calling RUN_ALL_TESTS().
 static bool GTestIsInitialized() { return GetArgvs().size() > 0; }
 
-// Iterates over a vector of TestCases, keeping a running sum of the
+// Iterates over a vector of TestSuites, keeping a running sum of the
 // results of calling a given int-returning method on each.
 // Returns the sum.
-static int SumOverTestCaseList(const std::vector<TestCase*>& case_list,
-                               int (TestCase::*method)() const) {
+static int SumOverTestSuiteList(const std::vector<TestSuite*>& case_list,
+                                int (TestSuite::*method)() const) {
   int sum = 0;
   for (size_t i = 0; i < case_list.size(); i++) {
     sum += (case_list[i]->*method)();
@@ -1789,20 +1847,20 @@
   return sum;
 }
 
-// Returns true iff the test case passed.
-static bool TestCasePassed(const TestCase* test_case) {
-  return test_case->should_run() && test_case->Passed();
+// Returns true iff the test suite passed.
+static bool TestSuitePassed(const TestSuite* test_suite) {
+  return test_suite->should_run() && test_suite->Passed();
 }
 
-// Returns true iff the test case failed.
-static bool TestCaseFailed(const TestCase* test_case) {
-  return test_case->should_run() && test_case->Failed();
+// Returns true iff the test suite failed.
+static bool TestSuiteFailed(const TestSuite* test_suite) {
+  return test_suite->should_run() && test_suite->Failed();
 }
 
-// Returns true iff test_case contains at least one test that should
+// Returns true iff test_suite contains at least one test that should
 // run.
-static bool ShouldRunTestCase(const TestCase* test_case) {
-  return test_case->should_run();
+static bool ShouldRunTestSuite(const TestSuite* test_suite) {
+  return test_suite->should_run();
 }
 
 // AssertHelper constructor.
@@ -1828,16 +1886,16 @@
                       );  // NOLINT
 }
 
-// Mutex for linked pointers.
-GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
-
 // A copy of all command line arguments.  Set by InitGoogleTest().
-::std::vector<testing::internal::string> g_argvs;
+static ::std::vector<std::string> g_argvs;
 
-const ::std::vector<testing::internal::string>& GetArgvs() {
+::std::vector<std::string> GetArgvs() {
 #if defined(GTEST_CUSTOM_GET_ARGVS_)
-  return GTEST_CUSTOM_GET_ARGVS_();
-#else  // defined(GTEST_CUSTOM_GET_ARGVS_)
+  // GTEST_CUSTOM_GET_ARGVS_() may return a container of std::string or
+  // ::string. This code converts it to the appropriate type.
+  const auto& custom = GTEST_CUSTOM_GET_ARGVS_();
+  return ::std::vector<std::string>(custom.begin(), custom.end());
+#else   // defined(GTEST_CUSTOM_GET_ARGVS_)
   return g_argvs;
 #endif  // defined(GTEST_CUSTOM_GET_ARGVS_)
 }
@@ -1847,7 +1905,7 @@
 FilePath GetCurrentExecutableName() {
   FilePath result;
 
-#if GTEST_OS_WINDOWS
+#if GTEST_OS_WINDOWS || GTEST_OS_OS2
   result.Set(FilePath(GetArgvs()[0]).RemoveExtension("exe"));
 #else
   result.Set(FilePath(GetArgvs()[0]));
@@ -1861,34 +1919,31 @@
 // Returns the output format, or "" for normal printed output.
 std::string UnitTestOptions::GetOutputFormat() {
   const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
-  if (gtest_output_flag == NULL) return std::string("");
-
   const char* const colon = strchr(gtest_output_flag, ':');
-  return (colon == NULL) ?
-      std::string(gtest_output_flag) :
-      std::string(gtest_output_flag, colon - gtest_output_flag);
+  return (colon == nullptr)
+             ? std::string(gtest_output_flag)
+             : std::string(gtest_output_flag, colon - gtest_output_flag);
 }
 
 // Returns the name of the requested output file, or the default if none
 // was explicitly specified.
 std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
   const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
-  if (gtest_output_flag == NULL)
-    return "";
+
+  std::string format = GetOutputFormat();
+  if (format.empty())
+    format = std::string(kDefaultOutputFormat);
 
   const char* const colon = strchr(gtest_output_flag, ':');
-  if (colon == NULL)
-    return internal::FilePath::ConcatPaths(
+  if (colon == nullptr)
+    return internal::FilePath::MakeFileName(
         internal::FilePath(
             UnitTest::GetInstance()->original_working_dir()),
-        internal::FilePath(kDefaultOutputFile)).string();
+        internal::FilePath(kDefaultOutputFile), 0,
+        format.c_str()).string();
 
   internal::FilePath output_name(colon + 1);
   if (!output_name.IsAbsolutePath())
-    // TODO(wan@google.com): on Windows \some\path is not an absolute
-    // path (as its meaning depends on the current drive), yet the
-    // following logic for turning it into an absolute path is wrong.
-    // Fix it.
     output_name = internal::FilePath::ConcatPaths(
         internal::FilePath(UnitTest::GetInstance()->original_working_dir()),
         internal::FilePath(colon + 1));
@@ -1936,7 +1991,7 @@
     cur_pattern = strchr(cur_pattern, ':');
 
     // Returns if no more pattern can be found.
-    if (cur_pattern == NULL) {
+    if (cur_pattern == nullptr) {
       return false;
     }
 
@@ -1945,11 +2000,11 @@
   }
 }
 
-// Returns true iff the user-specified filter matches the test case
+// Returns true iff the user-specified filter matches the test suite
 // name and the test name.
-bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name,
-                                        const std::string &test_name) {
-  const std::string& full_name = test_case_name + "." + test_name.c_str();
+bool UnitTestOptions::FilterMatchesTest(const std::string& test_suite_name,
+                                        const std::string& test_name) {
+  const std::string& full_name = test_suite_name + "." + test_name.c_str();
 
   // Split --gtest_filter at '-', if there is one, to separate into
   // positive filter and negative filter portions
@@ -1957,7 +2012,7 @@
   const char* const dash = strchr(p, '-');
   std::string positive;
   std::string negative;
-  if (dash == NULL) {
+  if (dash == nullptr) {
     positive = GTEST_FLAG(filter).c_str();  // Whole string is a positive filter
     negative = "";
   } else {
@@ -2076,12 +2131,12 @@
 // This predicate-formatter checks that 'results' contains a test part
 // failure of the given type and that the failure message contains the
 // given substring.
-AssertionResult HasOneFailure(const char* /* results_expr */,
-                              const char* /* type_expr */,
-                              const char* /* substr_expr */,
-                              const TestPartResultArray& results,
-                              TestPartResult::Type type,
-                              const string& substr) {
+static AssertionResult HasOneFailure(const char* /* results_expr */,
+                                     const char* /* type_expr */,
+                                     const char* /* substr_expr */,
+                                     const TestPartResultArray& results,
+                                     TestPartResult::Type type,
+                                     const std::string& substr) {
   const std::string expected(type == TestPartResult::kFatalFailure ?
                         "1 fatal failure" :
                         "1 non-fatal failure");
@@ -2102,7 +2157,7 @@
                               << r;
   }
 
-  if (strstr(r.message(), substr.c_str()) == NULL) {
+  if (strstr(r.message(), substr.c_str()) == nullptr) {
     return AssertionFailure() << "Expected: " << expected << " containing \""
                               << substr << "\"\n"
                               << "  Actual:\n"
@@ -2115,13 +2170,10 @@
 // The constructor of SingleFailureChecker remembers where to look up
 // test part results, what type of failure we expect, and what
 // substring the failure message should contain.
-SingleFailureChecker:: SingleFailureChecker(
-    const TestPartResultArray* results,
-    TestPartResult::Type type,
-    const string& substr)
-    : results_(results),
-      type_(type),
-      substr_(substr) {}
+SingleFailureChecker::SingleFailureChecker(const TestPartResultArray* results,
+                                           TestPartResult::Type type,
+                                           const std::string& substr)
+    : results_(results), type_(type), substr_(substr) {}
 
 // The destructor of SingleFailureChecker verifies that the given
 // TestPartResultArray contains exactly one failure that has the given
@@ -2174,61 +2226,66 @@
   per_thread_test_part_result_reporter_.set(reporter);
 }
 
-// Gets the number of successful test cases.
-int UnitTestImpl::successful_test_case_count() const {
-  return CountIf(test_cases_, TestCasePassed);
+// Gets the number of successful test suites.
+int UnitTestImpl::successful_test_suite_count() const {
+  return CountIf(test_suites_, TestSuitePassed);
 }
 
-// Gets the number of failed test cases.
-int UnitTestImpl::failed_test_case_count() const {
-  return CountIf(test_cases_, TestCaseFailed);
+// Gets the number of failed test suites.
+int UnitTestImpl::failed_test_suite_count() const {
+  return CountIf(test_suites_, TestSuiteFailed);
 }
 
-// Gets the number of all test cases.
-int UnitTestImpl::total_test_case_count() const {
-  return static_cast<int>(test_cases_.size());
+// Gets the number of all test suites.
+int UnitTestImpl::total_test_suite_count() const {
+  return static_cast<int>(test_suites_.size());
 }
 
-// Gets the number of all test cases that contain at least one test
+// Gets the number of all test suites that contain at least one test
 // that should run.
-int UnitTestImpl::test_case_to_run_count() const {
-  return CountIf(test_cases_, ShouldRunTestCase);
+int UnitTestImpl::test_suite_to_run_count() const {
+  return CountIf(test_suites_, ShouldRunTestSuite);
 }
 
 // Gets the number of successful tests.
 int UnitTestImpl::successful_test_count() const {
-  return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count);
+  return SumOverTestSuiteList(test_suites_, &TestSuite::successful_test_count);
+}
+
+// Gets the number of skipped tests.
+int UnitTestImpl::skipped_test_count() const {
+  return SumOverTestSuiteList(test_suites_, &TestSuite::skipped_test_count);
 }
 
 // Gets the number of failed tests.
 int UnitTestImpl::failed_test_count() const {
-  return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count);
+  return SumOverTestSuiteList(test_suites_, &TestSuite::failed_test_count);
 }
 
 // Gets the number of disabled tests that will be reported in the XML report.
 int UnitTestImpl::reportable_disabled_test_count() const {
-  return SumOverTestCaseList(test_cases_,
-                             &TestCase::reportable_disabled_test_count);
+  return SumOverTestSuiteList(test_suites_,
+                              &TestSuite::reportable_disabled_test_count);
 }
 
 // Gets the number of disabled tests.
 int UnitTestImpl::disabled_test_count() const {
-  return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count);
+  return SumOverTestSuiteList(test_suites_, &TestSuite::disabled_test_count);
 }
 
 // Gets the number of tests to be printed in the XML report.
 int UnitTestImpl::reportable_test_count() const {
-  return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count);
+  return SumOverTestSuiteList(test_suites_, &TestSuite::reportable_test_count);
 }
 
 // Gets the number of all tests.
 int UnitTestImpl::total_test_count() const {
-  return SumOverTestCaseList(test_cases_, &TestCase::total_test_count);
+  return SumOverTestSuiteList(test_suites_, &TestSuite::total_test_count);
 }
 
 // Gets the number of tests that should run.
 int UnitTestImpl::test_to_run_count() const {
-  return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count);
+  return SumOverTestSuiteList(test_suites_, &TestSuite::test_to_run_count);
 }
 
 // Returns the current OS stack trace as an std::string.
@@ -2262,8 +2319,6 @@
   SYSTEMTIME now_systime;
   FILETIME now_filetime;
   ULARGE_INTEGER now_int64;
-  // TODO(kenton@google.com): Shouldn't this just use
-  //   GetSystemTimeAsFileTime()?
   GetSystemTime(&now_systime);
   if (SystemTimeToFileTime(&now_systime, &now_filetime)) {
     now_int64.LowPart = now_filetime.dwLowDateTime;
@@ -2278,16 +2333,14 @@
 
   // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996
   // (deprecated function) there.
-  // TODO(kenton@google.com): Use GetTickCount()?  Or use
-  //   SystemTimeToFileTime()
-  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
+  GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
   _ftime64(&now);
-  GTEST_DISABLE_MSC_WARNINGS_POP_()
+  GTEST_DISABLE_MSC_DEPRECATED_POP_()
 
   return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm;
 #elif GTEST_HAS_GETTIMEOFDAY_
   struct timeval now;
-  gettimeofday(&now, NULL);
+  gettimeofday(&now, nullptr);
   return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000;
 #else
 # error "Don't know how to get the current time on your system."
@@ -2304,11 +2357,10 @@
 // value using delete[]. Returns the wide string, or NULL if the
 // input is NULL.
 LPCWSTR String::AnsiToUtf16(const char* ansi) {
-  if (!ansi) return NULL;
+  if (!ansi) return nullptr;
   const int length = strlen(ansi);
   const int unicode_length =
-      MultiByteToWideChar(CP_ACP, 0, ansi, length,
-                          NULL, 0);
+      MultiByteToWideChar(CP_ACP, 0, ansi, length, nullptr, 0);
   WCHAR* unicode = new WCHAR[unicode_length + 1];
   MultiByteToWideChar(CP_ACP, 0, ansi, length,
                       unicode, unicode_length);
@@ -2321,13 +2373,12 @@
 // value using delete[]. Returns the ANSI string, or NULL if the
 // input is NULL.
 const char* String::Utf16ToAnsi(LPCWSTR utf16_str)  {
-  if (!utf16_str) return NULL;
-  const int ansi_length =
-      WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
-                          NULL, 0, NULL, NULL);
+  if (!utf16_str) return nullptr;
+  const int ansi_length = WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, nullptr,
+                                              0, nullptr, nullptr);
   char* ansi = new char[ansi_length + 1];
-  WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
-                      ansi, ansi_length, NULL, NULL);
+  WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, ansi, ansi_length, nullptr,
+                      nullptr);
   ansi[ansi_length] = 0;
   return ansi;
 }
@@ -2340,9 +2391,9 @@
 // C string is considered different to any non-NULL C string,
 // including the empty string.
 bool String::CStringEquals(const char * lhs, const char * rhs) {
-  if ( lhs == NULL ) return rhs == NULL;
+  if (lhs == nullptr) return rhs == nullptr;
 
-  if ( rhs == NULL ) return false;
+  if (rhs == nullptr) return false;
 
   return strcmp(lhs, rhs) == 0;
 }
@@ -2434,10 +2485,9 @@
 // Used in EXPECT_TRUE/FALSE(assertion_result).
 AssertionResult::AssertionResult(const AssertionResult& other)
     : success_(other.success_),
-      message_(other.message_.get() != NULL ?
-               new ::std::string(*other.message_) :
-               static_cast< ::std::string*>(NULL)) {
-}
+      message_(other.message_.get() != nullptr
+                   ? new ::std::string(*other.message_)
+                   : static_cast< ::std::string*>(nullptr)) {}
 
 // Swaps two AssertionResults.
 void AssertionResult::swap(AssertionResult& other) {
@@ -2449,8 +2499,7 @@
 // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
 AssertionResult AssertionResult::operator!() const {
   AssertionResult negation(!success_);
-  if (message_.get() != NULL)
-    negation << *message_;
+  if (message_.get() != nullptr) negation << *message_;
   return negation;
 }
 
@@ -2619,7 +2668,7 @@
   // Print a unified diff header for one hunk.
   // The format is
   //   "@@ -<left_start>,<left_length> +<right_start>,<right_length> @@"
-  // where the left/right parts are ommitted if unnecessary.
+  // where the left/right parts are omitted if unnecessary.
   void PrintHeader(std::ostream* ss) const {
     *ss << "@@ ";
     if (removes_) {
@@ -2763,13 +2812,14 @@
                           const std::string& rhs_value,
                           bool ignoring_case) {
   Message msg;
-  msg << "      Expected: " << lhs_expression;
+  msg << "Expected equality of these values:";
+  msg << "\n  " << lhs_expression;
   if (lhs_value != lhs_expression) {
-    msg << "\n      Which is: " << lhs_value;
+    msg << "\n    Which is: " << lhs_value;
   }
-  msg << "\nTo be equal to: " << rhs_expression;
+  msg << "\n  " << rhs_expression;
   if (rhs_value != rhs_expression) {
-    msg << "\n      Which is: " << rhs_value;
+    msg << "\n    Which is: " << rhs_value;
   }
 
   if (ignoring_case) {
@@ -2816,8 +2866,6 @@
   const double diff = fabs(val1 - val2);
   if (diff <= abs_error) return AssertionSuccess();
 
-  // TODO(wan): do not print the value of an expression if it's
-  // already a literal.
   return AssertionFailure()
       << "The difference between " << expr1 << " and " << expr2
       << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n"
@@ -3003,17 +3051,15 @@
 // only.
 
 bool IsSubstringPred(const char* needle, const char* haystack) {
-  if (needle == NULL || haystack == NULL)
-    return needle == haystack;
+  if (needle == nullptr || haystack == nullptr) return needle == haystack;
 
-  return strstr(haystack, needle) != NULL;
+  return strstr(haystack, needle) != nullptr;
 }
 
 bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {
-  if (needle == NULL || haystack == NULL)
-    return needle == haystack;
+  if (needle == nullptr || haystack == nullptr) return needle == haystack;
 
-  return wcsstr(haystack, needle) != NULL;
+  return wcsstr(haystack, needle) != nullptr;
 }
 
 // StringType here can be either ::std::string or ::std::wstring.
@@ -3111,7 +3157,7 @@
 AssertionResult HRESULTFailureHelper(const char* expr,
                                      const char* expected,
                                      long hr) {  // NOLINT
-# if GTEST_OS_WINDOWS_MOBILE
+# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_TV_TITLE
 
   // Windows CE doesn't support FormatMessage.
   const char error_text[] = "";
@@ -3127,12 +3173,12 @@
   // Gets the system's human readable message string for this HRESULT.
   char error_text[kBufSize] = { '\0' };
   DWORD message_length = ::FormatMessageA(kFlags,
-                                          0,  // no source, we're asking system
+                                          0,   // no source, we're asking system
                                           hr,  // the error
-                                          0,  // no line width restrictions
+                                          0,   // no line width restrictions
                                           error_text,  // output buffer
-                                          kBufSize,  // buf size
-                                          NULL);  // no arguments for inserts
+                                          kBufSize,    // buf size
+                                          nullptr);  // no arguments for inserts
   // Trims tailing white space (FormatMessage leaves a trailing CR-LF)
   for (; message_length && IsSpace(error_text[message_length - 1]);
           --message_length) {
@@ -3168,7 +3214,7 @@
 // Utility functions for encoding Unicode text (wide strings) in
 // UTF-8.
 
-// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8
+// A Unicode code-point can have up to 21 bits, and is encoded in UTF-8
 // like this:
 //
 // Code-point length   Encoding
@@ -3232,9 +3278,9 @@
   return str;
 }
 
-// The following two functions only make sense if the the system
+// The following two functions only make sense if the system
 // uses UTF-16 for wide string encoding. All supported systems
-// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16.
+// with 16 bit wchar_t (Windows, Cygwin) do use UTF-16.
 
 // Determines if the arguments constitute UTF-16 surrogate pair
 // and thus should be combined into a single Unicode code point
@@ -3257,7 +3303,7 @@
 
 // Converts a wide string to a narrow string in UTF-8 encoding.
 // The wide string is assumed to have the following encoding:
-//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin)
 //   UTF-32 if sizeof(wchar_t) == 4 (on Linux)
 // Parameter str points to a null-terminated wide string.
 // Parameter num_chars may additionally limit the number
@@ -3294,7 +3340,7 @@
 // Converts a wide C string to an std::string using the UTF-8 encoding.
 // NULL will be converted to "(null)".
 std::string String::ShowWideCString(const wchar_t * wide_c_str) {
-  if (wide_c_str == NULL)  return "(null)";
+  if (wide_c_str == nullptr) return "(null)";
 
   return internal::WideStringToUtf8(wide_c_str, -1);
 }
@@ -3306,9 +3352,9 @@
 // C string is considered different to any non-NULL C string,
 // including the empty string.
 bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) {
-  if (lhs == NULL) return rhs == NULL;
+  if (lhs == nullptr) return rhs == nullptr;
 
-  if (rhs == NULL) return false;
+  if (rhs == nullptr) return false;
 
   return wcscmp(lhs, rhs) == 0;
 }
@@ -3351,10 +3397,8 @@
 // NULL C string is considered different to any non-NULL C string,
 // including the empty string.
 bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) {
-  if (lhs == NULL)
-    return rhs == NULL;
-  if (rhs == NULL)
-    return false;
+  if (lhs == nullptr) return rhs == nullptr;
+  if (rhs == nullptr) return false;
   return posix::StrCaseCmp(lhs, rhs) == 0;
 }
 
@@ -3372,9 +3416,9 @@
   // current locale.
 bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
                                               const wchar_t* rhs) {
-  if (lhs == NULL) return rhs == NULL;
+  if (lhs == nullptr) return rhs == nullptr;
 
-  if (rhs == NULL) return false;
+  if (rhs == nullptr) return false;
 
 #if GTEST_OS_WINDOWS
   return _wcsicmp(lhs, rhs) == 0;
@@ -3544,13 +3588,8 @@
 
 // The list of reserved attributes used in the <testcase> element of XML output.
 static const char* const kReservedTestCaseAttributes[] = {
-  "classname",
-  "name",
-  "status",
-  "time",
-  "type_param",
-  "value_param"
-};
+    "classname",  "name",        "status", "time",
+    "type_param", "value_param", "file",   "line"};
 
 template <int kSize>
 std::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) {
@@ -3586,8 +3625,9 @@
   return word_list.GetString();
 }
 
-bool ValidateTestPropertyName(const std::string& property_name,
-                              const std::vector<std::string>& reserved_names) {
+static bool ValidateTestPropertyName(
+    const std::string& property_name,
+    const std::vector<std::string>& reserved_names) {
   if (std::find(reserved_names.begin(), reserved_names.end(), property_name) !=
           reserved_names.end()) {
     ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name
@@ -3614,6 +3654,16 @@
   elapsed_time_ = 0;
 }
 
+// Returns true off the test part was skipped.
+static bool TestPartSkipped(const TestPartResult& result) {
+  return result.skipped();
+}
+
+// Returns true iff the test was skipped.
+bool TestResult::Skipped() const {
+  return !Failed() && CountIf(test_part_results_, TestPartSkipped) > 0;
+}
+
 // Returns true iff the test failed.
 bool TestResult::Failed() const {
   for (int i = 0; i < total_part_count(); ++i) {
@@ -3701,25 +3751,25 @@
   // AddTestPartResult.
   UnitTest::GetInstance()->AddTestPartResult(
       result_type,
-      NULL,  // No info about the source file where the exception occurred.
-      -1,    // We have no info on which line caused the exception.
+      nullptr,  // No info about the source file where the exception occurred.
+      -1,       // We have no info on which line caused the exception.
       message,
-      "");   // No stack trace, either.
+      "");  // No stack trace, either.
 }
 
 }  // namespace internal
 
-// Google Test requires all tests in the same test case to use the same test
+// Google Test requires all tests in the same test suite to use the same test
 // fixture class.  This function checks if the current test has the
-// same fixture class as the first test in the current test case.  If
+// same fixture class as the first test in the current test suite.  If
 // yes, it returns true; otherwise it generates a Google Test failure and
 // returns false.
 bool Test::HasSameFixtureClass() {
   internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
-  const TestCase* const test_case = impl->current_test_case();
+  const TestSuite* const test_suite = impl->current_test_suite();
 
-  // Info about the first test in the current test case.
-  const TestInfo* const first_test_info = test_case->test_info_list()[0];
+  // Info about the first test in the current test suite.
+  const TestInfo* const first_test_info = test_suite->test_info_list()[0];
   const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_;
   const char* const first_test_name = first_test_info->name();
 
@@ -3735,7 +3785,7 @@
     const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId();
 
     if (first_is_TEST || this_is_TEST) {
-      // Both TEST and TEST_F appear in same test case, which is incorrect.
+      // Both TEST and TEST_F appear in same test suite, which is incorrect.
       // Tell the user how to fix this.
 
       // Gets the name of the TEST and the name of the TEST_F.  Note
@@ -3747,9 +3797,9 @@
           first_is_TEST ? this_test_name : first_test_name;
 
       ADD_FAILURE()
-          << "All tests in the same test case must use the same test fixture\n"
-          << "class, so mixing TEST_F and TEST in the same test case is\n"
-          << "illegal.  In test case " << this_test_info->test_case_name()
+          << "All tests in the same test suite must use the same test fixture\n"
+          << "class, so mixing TEST_F and TEST in the same test suite is\n"
+          << "illegal.  In test suite " << this_test_info->test_suite_name()
           << ",\n"
           << "test " << TEST_F_name << " is defined using TEST_F but\n"
           << "test " << TEST_name << " is defined using TEST.  You probably\n"
@@ -3759,15 +3809,15 @@
       // Two fixture classes with the same name appear in two different
       // namespaces, which is not allowed. Tell the user how to fix this.
       ADD_FAILURE()
-          << "All tests in the same test case must use the same test fixture\n"
-          << "class.  However, in test case "
-          << this_test_info->test_case_name() << ",\n"
-          << "you defined test " << first_test_name
-          << " and test " << this_test_name << "\n"
+          << "All tests in the same test suite must use the same test fixture\n"
+          << "class.  However, in test suite "
+          << this_test_info->test_suite_name() << ",\n"
+          << "you defined test " << first_test_name << " and test "
+          << this_test_name << "\n"
           << "using two different test fixture classes.  This can happen if\n"
           << "the two classes are from different namespaces or translation\n"
           << "units and have the same name.  You should probably rename one\n"
-          << "of the classes to put the tests into different test cases.";
+          << "of the classes to put the tests into different test suites.";
     }
     return false;
   }
@@ -3800,7 +3850,7 @@
 static std::string FormatCxxExceptionMessage(const char* description,
                                              const char* location) {
   Message message;
-  if (description != NULL) {
+  if (description != nullptr) {
     message << "C++ exception with description \"" << description << "\"";
   } else {
     message << "Unknown C++ exception";
@@ -3884,6 +3934,8 @@
 #if GTEST_HAS_EXCEPTIONS
     try {
       return HandleSehExceptionsInMethodIfSupported(object, method, location);
+    } catch (const AssertionException&) {  // NOLINT
+      // This failure was reported already.
     } catch (const internal::GoogleTestFailureException&) {  // NOLINT
       // This exception type can only be thrown by a failed Google
       // Test assertion with the intention of letting another testing
@@ -3896,7 +3948,7 @@
     } catch (...) {  // NOLINT
       internal::ReportFailureInUnknownLocation(
           TestPartResult::kFatalFailure,
-          FormatCxxExceptionMessage(NULL, location));
+          FormatCxxExceptionMessage(nullptr, location));
     }
     return static_cast<Result>(0);
 #else
@@ -3916,8 +3968,9 @@
   internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
   impl->os_stack_trace_getter()->UponLeavingGTest();
   internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()");
-  // We will run the test only if SetUp() was successful.
-  if (!HasFatalFailure()) {
+  // We will run the test only if SetUp() was successful and didn't call
+  // GTEST_SKIP().
+  if (!HasFatalFailure() && !IsSkipped()) {
     impl->os_stack_trace_getter()->UponLeavingGTest();
     internal::HandleExceptionsInMethodIfSupported(
         this, &Test::TestBody, "the test body");
@@ -3942,21 +3995,25 @@
       HasNonfatalFailure();
 }
 
+// Returns true iff the current test was skipped.
+bool Test::IsSkipped() {
+  return internal::GetUnitTestImpl()->current_test_result()->Skipped();
+}
+
 // class TestInfo
 
 // Constructs a TestInfo object. It assumes ownership of the test factory
 // object.
-TestInfo::TestInfo(const std::string& a_test_case_name,
-                   const std::string& a_name,
-                   const char* a_type_param,
+TestInfo::TestInfo(const std::string& a_test_suite_name,
+                   const std::string& a_name, const char* a_type_param,
                    const char* a_value_param,
                    internal::CodeLocation a_code_location,
                    internal::TypeId fixture_class_id,
                    internal::TestFactoryBase* factory)
-    : test_case_name_(a_test_case_name),
+    : test_suite_name_(a_test_suite_name),
       name_(a_name),
-      type_param_(a_type_param ? new std::string(a_type_param) : NULL),
-      value_param_(a_value_param ? new std::string(a_value_param) : NULL),
+      type_param_(a_type_param ? new std::string(a_type_param) : nullptr),
+      value_param_(a_value_param ? new std::string(a_value_param) : nullptr),
       location_(a_code_location),
       fixture_class_id_(fixture_class_id),
       should_run_(false),
@@ -3975,7 +4032,7 @@
 //
 // Arguments:
 //
-//   test_case_name:   name of the test case
+//   test_suite_name:   name of the test suite
 //   name:             name of the test
 //   type_param:       the name of the test's type parameter, or NULL if
 //                     this is not a typed or a type-parameterized test.
@@ -3983,49 +4040,40 @@
 //                     or NULL if this is not a value-parameterized test.
 //   code_location:    code location where the test is defined
 //   fixture_class_id: ID of the test fixture class
-//   set_up_tc:        pointer to the function that sets up the test case
-//   tear_down_tc:     pointer to the function that tears down the test case
+//   set_up_tc:        pointer to the function that sets up the test suite
+//   tear_down_tc:     pointer to the function that tears down the test suite
 //   factory:          pointer to the factory that creates a test object.
 //                     The newly created TestInfo instance will assume
 //                     ownership of the factory object.
 TestInfo* MakeAndRegisterTestInfo(
-    const char* test_case_name,
-    const char* name,
-    const char* type_param,
-    const char* value_param,
-    CodeLocation code_location,
-    TypeId fixture_class_id,
-    SetUpTestCaseFunc set_up_tc,
-    TearDownTestCaseFunc tear_down_tc,
-    TestFactoryBase* factory) {
+    const char* test_suite_name, const char* name, const char* type_param,
+    const char* value_param, CodeLocation code_location,
+    TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
+    TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory) {
   TestInfo* const test_info =
-      new TestInfo(test_case_name, name, type_param, value_param,
+      new TestInfo(test_suite_name, name, type_param, value_param,
                    code_location, fixture_class_id, factory);
   GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
   return test_info;
 }
 
-#if GTEST_HAS_PARAM_TEST
-void ReportInvalidTestCaseType(const char* test_case_name,
-                               CodeLocation code_location) {
+void ReportInvalidTestSuiteType(const char* test_suite_name,
+                                CodeLocation code_location) {
   Message errors;
   errors
-      << "Attempted redefinition of test case " << test_case_name << ".\n"
-      << "All tests in the same test case must use the same test fixture\n"
-      << "class.  However, in test case " << test_case_name << ", you tried\n"
+      << "Attempted redefinition of test suite " << test_suite_name << ".\n"
+      << "All tests in the same test suite must use the same test fixture\n"
+      << "class.  However, in test suite " << test_suite_name << ", you tried\n"
       << "to define a test using a fixture class different from the one\n"
       << "used earlier. This can happen if the two fixture classes are\n"
       << "from different namespaces and have the same name. You should\n"
       << "probably rename one of the classes to put the tests into different\n"
-      << "test cases.";
+      << "test suites.";
 
-  fprintf(stderr, "%s %s",
-          FormatFileLocation(code_location.file.c_str(),
-                             code_location.line).c_str(),
-          errors.GetString().c_str());
+  GTEST_LOG_(ERROR) << FormatFileLocation(code_location.file.c_str(),
+                                          code_location.line)
+                    << " " << errors.GetString();
 }
-#endif  // GTEST_HAS_PARAM_TEST
-
 }  // namespace internal
 
 namespace {
@@ -4033,7 +4081,7 @@
 // A predicate that checks the test name of a TestInfo against a known
 // value.
 //
-// This is used for implementation of the TestCase class only.  We put
+// This is used for implementation of the TestSuite class only.  We put
 // it in the anonymous namespace to prevent polluting the outer
 // namespace.
 //
@@ -4060,15 +4108,13 @@
 namespace internal {
 
 // This method expands all parameterized tests registered with macros TEST_P
-// and INSTANTIATE_TEST_CASE_P into regular tests and registers those.
+// and INSTANTIATE_TEST_SUITE_P into regular tests and registers those.
 // This will be done just once during the program runtime.
 void UnitTestImpl::RegisterParameterizedTests() {
-#if GTEST_HAS_PARAM_TEST
   if (!parameterized_tests_registered_) {
     parameterized_test_registry_.RegisterTests();
     parameterized_tests_registered_ = true;
   }
-#endif
 }
 
 }  // namespace internal
@@ -4096,18 +4142,21 @@
       factory_, &internal::TestFactoryBase::CreateTest,
       "the test fixture's constructor");
 
-  // Runs the test only if the test object was created and its
-  // constructor didn't generate a fatal failure.
-  if ((test != NULL) && !Test::HasFatalFailure()) {
+  // Runs the test if the constructor didn't generate a fatal failure or invoke
+  // GTEST_SKIP().
+  // Note that the object will not be null
+  if (!Test::HasFatalFailure() && !Test::IsSkipped()) {
     // This doesn't throw as all user code that can throw are wrapped into
     // exception handling code.
     test->Run();
   }
 
-  // Deletes the test object.
-  impl->os_stack_trace_getter()->UponLeavingGTest();
-  internal::HandleExceptionsInMethodIfSupported(
-      test, &Test::DeleteSelf_, "the test fixture's destructor");
+  if (test != nullptr) {
+    // Deletes the test object.
+    impl->os_stack_trace_getter()->UponLeavingGTest();
+    internal::HandleExceptionsInMethodIfSupported(
+        test, &Test::DeleteSelf_, "the test fixture's destructor");
+  }
 
   result_.set_elapsed_time(internal::GetTimeInMillis() - start);
 
@@ -4116,106 +4165,116 @@
 
   // Tells UnitTest to stop associating assertion results to this
   // test.
-  impl->set_current_test_info(NULL);
+  impl->set_current_test_info(nullptr);
 }
 
-// class TestCase
+// class TestSuite
 
-// Gets the number of successful tests in this test case.
-int TestCase::successful_test_count() const {
+// Gets the number of successful tests in this test suite.
+int TestSuite::successful_test_count() const {
   return CountIf(test_info_list_, TestPassed);
 }
 
-// Gets the number of failed tests in this test case.
-int TestCase::failed_test_count() const {
+// Gets the number of successful tests in this test suite.
+int TestSuite::skipped_test_count() const {
+  return CountIf(test_info_list_, TestSkipped);
+}
+
+// Gets the number of failed tests in this test suite.
+int TestSuite::failed_test_count() const {
   return CountIf(test_info_list_, TestFailed);
 }
 
 // Gets the number of disabled tests that will be reported in the XML report.
-int TestCase::reportable_disabled_test_count() const {
+int TestSuite::reportable_disabled_test_count() const {
   return CountIf(test_info_list_, TestReportableDisabled);
 }
 
-// Gets the number of disabled tests in this test case.
-int TestCase::disabled_test_count() const {
+// Gets the number of disabled tests in this test suite.
+int TestSuite::disabled_test_count() const {
   return CountIf(test_info_list_, TestDisabled);
 }
 
 // Gets the number of tests to be printed in the XML report.
-int TestCase::reportable_test_count() const {
+int TestSuite::reportable_test_count() const {
   return CountIf(test_info_list_, TestReportable);
 }
 
-// Get the number of tests in this test case that should run.
-int TestCase::test_to_run_count() const {
+// Get the number of tests in this test suite that should run.
+int TestSuite::test_to_run_count() const {
   return CountIf(test_info_list_, ShouldRunTest);
 }
 
 // Gets the number of all tests.
-int TestCase::total_test_count() const {
+int TestSuite::total_test_count() const {
   return static_cast<int>(test_info_list_.size());
 }
 
-// Creates a TestCase with the given name.
+// Creates a TestSuite with the given name.
 //
 // Arguments:
 //
-//   name:         name of the test case
-//   a_type_param: the name of the test case's type parameter, or NULL if
-//                 this is not a typed or a type-parameterized test case.
-//   set_up_tc:    pointer to the function that sets up the test case
-//   tear_down_tc: pointer to the function that tears down the test case
-TestCase::TestCase(const char* a_name, const char* a_type_param,
-                   Test::SetUpTestCaseFunc set_up_tc,
-                   Test::TearDownTestCaseFunc tear_down_tc)
+//   name:         name of the test suite
+//   a_type_param: the name of the test suite's type parameter, or NULL if
+//                 this is not a typed or a type-parameterized test suite.
+//   set_up_tc:    pointer to the function that sets up the test suite
+//   tear_down_tc: pointer to the function that tears down the test suite
+TestSuite::TestSuite(const char* a_name, const char* a_type_param,
+                     internal::SetUpTestSuiteFunc set_up_tc,
+                     internal::TearDownTestSuiteFunc tear_down_tc)
     : name_(a_name),
-      type_param_(a_type_param ? new std::string(a_type_param) : NULL),
+      type_param_(a_type_param ? new std::string(a_type_param) : nullptr),
       set_up_tc_(set_up_tc),
       tear_down_tc_(tear_down_tc),
       should_run_(false),
-      elapsed_time_(0) {
-}
+      elapsed_time_(0) {}
 
-// Destructor of TestCase.
-TestCase::~TestCase() {
+// Destructor of TestSuite.
+TestSuite::~TestSuite() {
   // Deletes every Test in the collection.
   ForEach(test_info_list_, internal::Delete<TestInfo>);
 }
 
 // Returns the i-th test among all the tests. i can range from 0 to
 // total_test_count() - 1. If i is not in that range, returns NULL.
-const TestInfo* TestCase::GetTestInfo(int i) const {
+const TestInfo* TestSuite::GetTestInfo(int i) const {
   const int index = GetElementOr(test_indices_, i, -1);
-  return index < 0 ? NULL : test_info_list_[index];
+  return index < 0 ? nullptr : test_info_list_[index];
 }
 
 // Returns the i-th test among all the tests. i can range from 0 to
 // total_test_count() - 1. If i is not in that range, returns NULL.
-TestInfo* TestCase::GetMutableTestInfo(int i) {
+TestInfo* TestSuite::GetMutableTestInfo(int i) {
   const int index = GetElementOr(test_indices_, i, -1);
-  return index < 0 ? NULL : test_info_list_[index];
+  return index < 0 ? nullptr : test_info_list_[index];
 }
 
-// Adds a test to this test case.  Will delete the test upon
-// destruction of the TestCase object.
-void TestCase::AddTestInfo(TestInfo * test_info) {
+// Adds a test to this test suite.  Will delete the test upon
+// destruction of the TestSuite object.
+void TestSuite::AddTestInfo(TestInfo* test_info) {
   test_info_list_.push_back(test_info);
   test_indices_.push_back(static_cast<int>(test_indices_.size()));
 }
 
-// Runs every test in this TestCase.
-void TestCase::Run() {
+// Runs every test in this TestSuite.
+void TestSuite::Run() {
   if (!should_run_) return;
 
   internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
-  impl->set_current_test_case(this);
+  impl->set_current_test_suite(this);
 
   TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
 
+  // Call both legacy and the new API
+  repeater->OnTestSuiteStart(*this);
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI
   repeater->OnTestCaseStart(*this);
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI
+
   impl->os_stack_trace_getter()->UponLeavingGTest();
   internal::HandleExceptionsInMethodIfSupported(
-      this, &TestCase::RunSetUpTestCase, "SetUpTestCase()");
+      this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()");
 
   const internal::TimeInMillis start = internal::GetTimeInMillis();
   for (int i = 0; i < total_test_count(); i++) {
@@ -4225,25 +4284,31 @@
 
   impl->os_stack_trace_getter()->UponLeavingGTest();
   internal::HandleExceptionsInMethodIfSupported(
-      this, &TestCase::RunTearDownTestCase, "TearDownTestCase()");
+      this, &TestSuite::RunTearDownTestSuite, "TearDownTestSuite()");
 
+  // Call both legacy and the new API
+  repeater->OnTestSuiteEnd(*this);
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI
   repeater->OnTestCaseEnd(*this);
-  impl->set_current_test_case(NULL);
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI
+
+  impl->set_current_test_suite(nullptr);
 }
 
-// Clears the results of all tests in this test case.
-void TestCase::ClearResult() {
+// Clears the results of all tests in this test suite.
+void TestSuite::ClearResult() {
   ad_hoc_test_result_.Clear();
   ForEach(test_info_list_, TestInfo::ClearTestResult);
 }
 
-// Shuffles the tests in this test case.
-void TestCase::ShuffleTests(internal::Random* random) {
+// Shuffles the tests in this test suite.
+void TestSuite::ShuffleTests(internal::Random* random) {
   Shuffle(random, &test_indices_);
 }
 
 // Restores the test order to before the first shuffle.
-void TestCase::UnshuffleTests() {
+void TestSuite::UnshuffleTests() {
   for (size_t i = 0; i < test_indices_.size(); i++) {
     test_indices_[i] = static_cast<int>(i);
   }
@@ -4266,9 +4331,9 @@
   return FormatCountableNoun(test_count, "test", "tests");
 }
 
-// Formats the count of test cases.
-static std::string FormatTestCaseCount(int test_case_count) {
-  return FormatCountableNoun(test_case_count, "test case", "test cases");
+// Formats the count of test suites.
+static std::string FormatTestSuiteCount(int test_suite_count) {
+  return FormatCountableNoun(test_suite_count, "test suite", "test suites");
 }
 
 // Converts a TestPartResult::Type enum to human-friendly string
@@ -4277,6 +4342,8 @@
 // between the two when viewing the test result.
 static const char * TestPartResultTypeToString(TestPartResult::Type type) {
   switch (type) {
+    case TestPartResult::kSkip:
+      return "Skipped";
     case TestPartResult::kSuccess:
       return "Success";
 
@@ -4324,19 +4391,11 @@
 }
 
 // class PrettyUnitTestResultPrinter
-
-enum GTestColor {
-  COLOR_DEFAULT,
-  COLOR_RED,
-  COLOR_GREEN,
-  COLOR_YELLOW
-};
-
 #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \
-    !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
+    !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW
 
 // Returns the character attribute for the given color.
-WORD GetColorAttribute(GTestColor color) {
+static WORD GetColorAttribute(GTestColor color) {
   switch (color) {
     case COLOR_RED:    return FOREGROUND_RED;
     case COLOR_GREEN:  return FOREGROUND_GREEN;
@@ -4345,16 +4404,48 @@
   }
 }
 
+static int GetBitOffset(WORD color_mask) {
+  if (color_mask == 0) return 0;
+
+  int bitOffset = 0;
+  while ((color_mask & 1) == 0) {
+    color_mask >>= 1;
+    ++bitOffset;
+  }
+  return bitOffset;
+}
+
+static WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
+  // Let's reuse the BG
+  static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN |
+                                      BACKGROUND_RED | BACKGROUND_INTENSITY;
+  static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN |
+                                      FOREGROUND_RED | FOREGROUND_INTENSITY;
+  const WORD existing_bg = old_color_attrs & background_mask;
+
+  WORD new_color =
+      GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY;
+  static const int bg_bitOffset = GetBitOffset(background_mask);
+  static const int fg_bitOffset = GetBitOffset(foreground_mask);
+
+  if (((new_color & background_mask) >> bg_bitOffset) ==
+      ((new_color & foreground_mask) >> fg_bitOffset)) {
+    new_color ^= FOREGROUND_INTENSITY;  // invert intensity
+  }
+  return new_color;
+}
+
 #else
 
 // Returns the ANSI color code for the given color.  COLOR_DEFAULT is
 // an invalid input.
-const char* GetAnsiColorCode(GTestColor color) {
+static const char* GetAnsiColorCode(GTestColor color) {
   switch (color) {
     case COLOR_RED:     return "1";
     case COLOR_GREEN:   return "2";
     case COLOR_YELLOW:  return "3";
-    default:            return NULL;
+    default:
+      return nullptr;
   };
 }
 
@@ -4365,7 +4456,7 @@
   const char* const gtest_color = GTEST_FLAG(color).c_str();
 
   if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) {
-#if GTEST_OS_WINDOWS
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
     // On Windows the TERM variable is usually not set, but the
     // console there does support colors.
     return stdout_is_tty;
@@ -4405,15 +4496,14 @@
   va_list args;
   va_start(args, fmt);
 
-#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || \
-    GTEST_OS_IOS || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
+#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS || GTEST_OS_IOS || \
+    GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
   const bool use_color = AlwaysFalse();
 #else
   static const bool in_color_mode =
       ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
   const bool use_color = in_color_mode && (color != COLOR_DEFAULT);
-#endif  // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
-  // The '!= 0' comparison is necessary to satisfy MSVC 7.1.
+#endif  // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS
 
   if (!use_color) {
     vprintf(fmt, args);
@@ -4422,20 +4512,21 @@
   }
 
 #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \
-    !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
+    !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW
   const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
 
   // Gets the current text color.
   CONSOLE_SCREEN_BUFFER_INFO buffer_info;
   GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
   const WORD old_color_attrs = buffer_info.wAttributes;
+  const WORD new_color = GetNewColor(color, old_color_attrs);
 
   // 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(stdout);
-  SetConsoleTextAttribute(stdout_handle,
-                          GetColorAttribute(color) | FOREGROUND_INTENSITY);
+  SetConsoleTextAttribute(stdout_handle, new_color);
+
   vprintf(fmt, args);
 
   fflush(stdout);
@@ -4449,23 +4540,22 @@
   va_end(args);
 }
 
-// Text printed in Google Test's text output and --gunit_list_tests
+// Text printed in Google Test's text output and --gtest_list_tests
 // output to label the type parameter and value parameter for a test.
 static const char kTypeParamLabel[] = "TypeParam";
 static const char kValueParamLabel[] = "GetParam()";
 
-void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
+static void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
   const char* const type_param = test_info.type_param();
   const char* const value_param = test_info.value_param();
 
-  if (type_param != NULL || value_param != NULL) {
+  if (type_param != nullptr || value_param != nullptr) {
     printf(", where ");
-    if (type_param != NULL) {
+    if (type_param != nullptr) {
       printf("%s = %s", kTypeParamLabel, type_param);
-      if (value_param != NULL)
-        printf(" and ");
+      if (value_param != nullptr) printf(" and ");
     }
-    if (value_param != NULL) {
+    if (value_param != nullptr) {
       printf("%s = %s", kValueParamLabel, value_param);
     }
   }
@@ -4477,27 +4567,28 @@
 class PrettyUnitTestResultPrinter : public TestEventListener {
  public:
   PrettyUnitTestResultPrinter() {}
-  static void PrintTestName(const char * test_case, const char * test) {
-    printf("%s.%s", test_case, test);
+  static void PrintTestName(const char* test_suite, const char* test) {
+    printf("%s.%s", test_suite, test);
   }
 
   // The following methods override what's in the TestEventListener class.
-  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
-  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
-  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
-  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
-  virtual void OnTestCaseStart(const TestCase& test_case);
-  virtual void OnTestStart(const TestInfo& test_info);
-  virtual void OnTestPartResult(const TestPartResult& result);
-  virtual void OnTestEnd(const TestInfo& test_info);
-  virtual void OnTestCaseEnd(const TestCase& test_case);
-  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
-  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
-  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
-  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+  void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
+  void OnTestIterationStart(const UnitTest& unit_test, int iteration) override;
+  void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override;
+  void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {}
+  void OnTestCaseStart(const TestSuite& test_suite) override;
+  void OnTestStart(const TestInfo& test_info) override;
+  void OnTestPartResult(const TestPartResult& result) override;
+  void OnTestEnd(const TestInfo& test_info) override;
+  void OnTestCaseEnd(const TestSuite& test_suite) override;
+  void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override;
+  void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {}
+  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
+  void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
 
  private:
   static void PrintFailedTests(const UnitTest& unit_test);
+  static void PrintSkippedTests(const UnitTest& unit_test);
 };
 
   // Fired before each iteration of tests starts.
@@ -4532,7 +4623,7 @@
   ColoredPrintf(COLOR_GREEN,  "[==========] ");
   printf("Running %s from %s.\n",
          FormatTestCount(unit_test.test_to_run_count()).c_str(),
-         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+         FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
   fflush(stdout);
 }
 
@@ -4543,22 +4634,22 @@
   fflush(stdout);
 }
 
-void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
+void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestSuite& test_suite) {
   const std::string counts =
-      FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
+      FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests");
   ColoredPrintf(COLOR_GREEN, "[----------] ");
-  printf("%s from %s", counts.c_str(), test_case.name());
-  if (test_case.type_param() == NULL) {
+  printf("%s from %s", counts.c_str(), test_suite.name());
+  if (test_suite.type_param() == nullptr) {
     printf("\n");
   } else {
-    printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param());
+    printf(", where %s = %s\n", kTypeParamLabel, test_suite.type_param());
   }
   fflush(stdout);
 }
 
 void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
   ColoredPrintf(COLOR_GREEN,  "[ RUN      ] ");
-  PrintTestName(test_info.test_case_name(), test_info.name());
+  PrintTestName(test_info.test_suite_name(), test_info.name());
   printf("\n");
   fflush(stdout);
 }
@@ -4566,22 +4657,29 @@
 // Called after an assertion failure.
 void PrettyUnitTestResultPrinter::OnTestPartResult(
     const TestPartResult& result) {
-  // If the test part succeeded, we don't need to do anything.
-  if (result.type() == TestPartResult::kSuccess)
-    return;
-
-  // Print failure message from the assertion (e.g. expected this and got that).
-  PrintTestPartResult(result);
-  fflush(stdout);
+  switch (result.type()) {
+    // If the test part succeeded, or was skipped,
+    // we don't need to do anything.
+    case TestPartResult::kSkip:
+    case TestPartResult::kSuccess:
+      return;
+    default:
+      // Print failure message from the assertion
+      // (e.g. expected this and got that).
+      PrintTestPartResult(result);
+      fflush(stdout);
+  }
 }
 
 void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
   if (test_info.result()->Passed()) {
     ColoredPrintf(COLOR_GREEN, "[       OK ] ");
+  } else if (test_info.result()->Skipped()) {
+    ColoredPrintf(COLOR_GREEN, "[  SKIPPED ] ");
   } else {
     ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
   }
-  PrintTestName(test_info.test_case_name(), test_info.name());
+  PrintTestName(test_info.test_suite_name(), test_info.name());
   if (test_info.result()->Failed())
     PrintFullTestCommentIfPresent(test_info);
 
@@ -4594,15 +4692,14 @@
   fflush(stdout);
 }
 
-void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
+void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestSuite& test_suite) {
   if (!GTEST_FLAG(print_time)) return;
 
   const std::string counts =
-      FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
+      FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests");
   ColoredPrintf(COLOR_GREEN, "[----------] ");
-  printf("%s from %s (%s ms total)\n\n",
-         counts.c_str(), test_case.name(),
-         internal::StreamableToString(test_case.elapsed_time()).c_str());
+  printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_suite.name(),
+         internal::StreamableToString(test_suite.elapsed_time()).c_str());
   fflush(stdout);
 }
 
@@ -4620,30 +4717,54 @@
     return;
   }
 
-  for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
-    const TestCase& test_case = *unit_test.GetTestCase(i);
-    if (!test_case.should_run() || (test_case.failed_test_count() == 0)) {
+  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
+    const TestSuite& test_suite = *unit_test.GetTestSuite(i);
+    if (!test_suite.should_run() || (test_suite.failed_test_count() == 0)) {
       continue;
     }
-    for (int j = 0; j < test_case.total_test_count(); ++j) {
-      const TestInfo& test_info = *test_case.GetTestInfo(j);
-      if (!test_info.should_run() || test_info.result()->Passed()) {
+    for (int j = 0; j < test_suite.total_test_count(); ++j) {
+      const TestInfo& test_info = *test_suite.GetTestInfo(j);
+      if (!test_info.should_run() || !test_info.result()->Failed()) {
         continue;
       }
       ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
-      printf("%s.%s", test_case.name(), test_info.name());
+      printf("%s.%s", test_suite.name(), test_info.name());
       PrintFullTestCommentIfPresent(test_info);
       printf("\n");
     }
   }
 }
 
+// Internal helper for printing the list of skipped tests.
+void PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) {
+  const int skipped_test_count = unit_test.skipped_test_count();
+  if (skipped_test_count == 0) {
+    return;
+  }
+
+  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
+    const TestSuite& test_suite = *unit_test.GetTestSuite(i);
+    if (!test_suite.should_run() || (test_suite.skipped_test_count() == 0)) {
+      continue;
+    }
+    for (int j = 0; j < test_suite.total_test_count(); ++j) {
+      const TestInfo& test_info = *test_suite.GetTestInfo(j);
+      if (!test_info.should_run() || !test_info.result()->Skipped()) {
+        continue;
+      }
+      ColoredPrintf(COLOR_GREEN, "[  SKIPPED ] ");
+      printf("%s.%s", test_suite.name(), test_info.name());
+      printf("\n");
+    }
+  }
+}
+
 void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
                                                      int /*iteration*/) {
   ColoredPrintf(COLOR_GREEN,  "[==========] ");
   printf("%s from %s ran.",
          FormatTestCount(unit_test.test_to_run_count()).c_str(),
-         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+         FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
   if (GTEST_FLAG(print_time)) {
     printf(" (%s ms total)",
            internal::StreamableToString(unit_test.elapsed_time()).c_str());
@@ -4652,6 +4773,13 @@
   ColoredPrintf(COLOR_GREEN,  "[  PASSED  ] ");
   printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str());
 
+  const int skipped_test_count = unit_test.skipped_test_count();
+  if (skipped_test_count > 0) {
+    ColoredPrintf(COLOR_GREEN, "[  SKIPPED ] ");
+    printf("%s, listed below:\n", FormatTestCount(skipped_test_count).c_str());
+    PrintSkippedTests(unit_test);
+  }
+
   int num_failures = unit_test.failed_test_count();
   if (!unit_test.Passed()) {
     const int failed_test_count = unit_test.failed_test_count();
@@ -4684,7 +4812,7 @@
 class TestEventRepeater : public TestEventListener {
  public:
   TestEventRepeater() : forwarding_enabled_(true) {}
-  virtual ~TestEventRepeater();
+  ~TestEventRepeater() override;
   void Append(TestEventListener *listener);
   TestEventListener* Release(TestEventListener* listener);
 
@@ -4693,19 +4821,27 @@
   bool forwarding_enabled() const { return forwarding_enabled_; }
   void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }
 
-  virtual void OnTestProgramStart(const UnitTest& unit_test);
-  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
-  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
-  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test);
-  virtual void OnTestCaseStart(const TestCase& test_case);
-  virtual void OnTestStart(const TestInfo& test_info);
-  virtual void OnTestPartResult(const TestPartResult& result);
-  virtual void OnTestEnd(const TestInfo& test_info);
-  virtual void OnTestCaseEnd(const TestCase& test_case);
-  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
-  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test);
-  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
-  virtual void OnTestProgramEnd(const UnitTest& unit_test);
+  void OnTestProgramStart(const UnitTest& unit_test) override;
+  void OnTestIterationStart(const UnitTest& unit_test, int iteration) override;
+  void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override;
+  void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) override;
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI
+  void OnTestCaseStart(const TestSuite& parameter) override;
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI
+  void OnTestSuiteStart(const TestSuite& parameter) override;
+  void OnTestStart(const TestInfo& test_info) override;
+  void OnTestPartResult(const TestPartResult& result) override;
+  void OnTestEnd(const TestInfo& test_info) override;
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI
+  void OnTestCaseEnd(const TestSuite& parameter) override;
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI
+  void OnTestSuiteEnd(const TestSuite& parameter) override;
+  void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override;
+  void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) override;
+  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
+  void OnTestProgramEnd(const UnitTest& unit_test) override;
 
  private:
   // Controls whether events will be forwarded to listeners_. Set to false
@@ -4725,7 +4861,6 @@
   listeners_.push_back(listener);
 }
 
-// TODO(vladl@google.com): Factor the search functionality into Vector::Find.
 TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
   for (size_t i = 0; i < listeners_.size(); ++i) {
     if (listeners_[i] == listener) {
@@ -4734,7 +4869,7 @@
     }
   }
 
-  return NULL;
+  return nullptr;
 }
 
 // Since most methods are very similar, use macros to reduce boilerplate.
@@ -4760,14 +4895,22 @@
 
 GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest)
 GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest)
-GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase)
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+GTEST_REPEATER_METHOD_(OnTestCaseStart, TestSuite)
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+GTEST_REPEATER_METHOD_(OnTestSuiteStart, TestSuite)
 GTEST_REPEATER_METHOD_(OnTestStart, TestInfo)
 GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)
 GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)
 GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)
 GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest)
 GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo)
-GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase)
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestSuite)
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+GTEST_REVERSE_REPEATER_METHOD_(OnTestSuiteEnd, TestSuite)
 GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)
 
 #undef GTEST_REPEATER_METHOD_
@@ -4798,7 +4941,12 @@
  public:
   explicit XmlUnitTestResultPrinter(const char* output_file);
 
-  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
+  void ListTestsMatchingFilter(const std::vector<TestSuite*>& test_suites);
+
+  // Prints an XML summary of all unit tests.
+  static void PrintXmlTestsList(std::ostream* stream,
+                                const std::vector<TestSuite*>& test_suites);
 
  private:
   // Is c a whitespace character that is normalized to a space character
@@ -4843,12 +4991,12 @@
 
   // Streams an XML representation of a TestInfo object.
   static void OutputXmlTestInfo(::std::ostream* stream,
-                                const char* test_case_name,
+                                const char* test_suite_name,
                                 const TestInfo& test_info);
 
-  // Prints an XML representation of a TestCase object
-  static void PrintXmlTestCase(::std::ostream* stream,
-                               const TestCase& test_case);
+  // Prints an XML representation of a TestSuite object
+  static void PrintXmlTestSuite(::std::ostream* stream,
+                                const TestSuite& test_suite);
 
   // Prints an XML summary of unit_test to output stream out.
   static void PrintXmlUnitTest(::std::ostream* stream,
@@ -4860,6 +5008,11 @@
   // to delimit this attribute from prior attributes.
   static std::string TestPropertiesAsXmlAttributes(const TestResult& result);
 
+  // Streams an XML representation of the test properties of a TestResult
+  // object.
+  static void OutputXmlTestProperties(std::ostream* stream,
+                                      const TestResult& result);
+
   // The output file.
   const std::string output_file_;
 
@@ -4869,46 +5022,30 @@
 // Creates a new XmlUnitTestResultPrinter.
 XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
     : output_file_(output_file) {
-  if (output_file_.c_str() == NULL || output_file_.empty()) {
-    fprintf(stderr, "XML output file may not be null\n");
-    fflush(stderr);
-    exit(EXIT_FAILURE);
+  if (output_file_.empty()) {
+    GTEST_LOG_(FATAL) << "XML output file may not be null";
   }
 }
 
 // Called after the unit test ends.
 void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
                                                   int /*iteration*/) {
-  FILE* xmlout = NULL;
-  FilePath output_file(output_file_);
-  FilePath output_dir(output_file.RemoveFileName());
-
-  if (output_dir.CreateDirectoriesRecursively()) {
-    xmlout = posix::FOpen(output_file_.c_str(), "w");
-  }
-  if (xmlout == NULL) {
-    // TODO(wan): report the reason of the failure.
-    //
-    // We don't do it for now as:
-    //
-    //   1. There is no urgent need for it.
-    //   2. It's a bit involved to make the errno variable thread-safe on
-    //      all three operating systems (Linux, Windows, and Mac OS).
-    //   3. To interpret the meaning of errno in a thread-safe way,
-    //      we need the strerror_r() function, which is not available on
-    //      Windows.
-    fprintf(stderr,
-            "Unable to open file \"%s\"\n",
-            output_file_.c_str());
-    fflush(stderr);
-    exit(EXIT_FAILURE);
-  }
+  FILE* xmlout = OpenFileForWriting(output_file_);
   std::stringstream stream;
   PrintXmlUnitTest(&stream, unit_test);
   fprintf(xmlout, "%s", StringStreamToString(&stream).c_str());
   fclose(xmlout);
 }
 
+void XmlUnitTestResultPrinter::ListTestsMatchingFilter(
+    const std::vector<TestSuite*>& test_suites) {
+  FILE* xmlout = OpenFileForWriting(output_file_);
+  std::stringstream stream;
+  PrintXmlTestsList(&stream, test_suites);
+  fprintf(xmlout, "%s", StringStreamToString(&stream).c_str());
+  fclose(xmlout);
+}
+
 // Returns an XML-escaped copy of the input string str.  If is_attribute
 // is true, the text is meant to appear as an attribute value, and
 // normalizable whitespace is preserved by replacing it with character
@@ -4919,8 +5056,6 @@
 // module will consist of ordinary English text.
 // If this module is ever modified to produce version 1.1 XML output,
 // most invalid characters can be retained using character references.
-// TODO(wan): It might be nice to have a minimally invasive, human-readable
-// escaping scheme for invalid characters, rather than dropping them.
 std::string XmlUnitTestResultPrinter::EscapeXml(
     const std::string& str, bool is_attribute) {
   Message m;
@@ -4980,11 +5115,12 @@
 
 // The following routines generate an XML representation of a UnitTest
 // object.
+// GOOGLETEST_CM0009 DO NOT DELETE
 //
 // This is how Google Test concepts map to the DTD:
 //
 // <testsuites name="AllTests">        <-- corresponds to a UnitTest object
-//   <testsuite name="testcase-name">  <-- corresponds to a TestCase object
+//   <testsuite name="testcase-name">  <-- corresponds to a TestSuite object
 //     <testcase name="test-name">     <-- corresponds to a TestInfo object
 //       <failure message="...">...</failure>
 //       <failure message="...">...</failure>
@@ -5008,12 +5144,11 @@
   // MINGW <time.h> provides neither localtime_r nor localtime_s, but uses
   // Windows' localtime(), which has a thread-local tm buffer.
   struct tm* tm_ptr = localtime(&seconds);  // NOLINT
-  if (tm_ptr == NULL)
-    return false;
+  if (tm_ptr == nullptr) return false;
   *out = *tm_ptr;
   return true;
 #else
-  return localtime_r(&seconds, out) != NULL;
+  return localtime_r(&seconds, out) != nullptr;
 #endif
 }
 
@@ -5039,7 +5174,7 @@
   *stream << "<![CDATA[";
   for (;;) {
     const char* const next_segment = strstr(segment, "]]>");
-    if (next_segment != NULL) {
+    if (next_segment != nullptr) {
       stream->write(
           segment, static_cast<std::streamsize>(next_segment - segment));
       *stream << "]]>]]&gt;<![CDATA[";
@@ -5069,30 +5204,41 @@
 }
 
 // Prints an XML representation of a TestInfo object.
-// TODO(wan): There is also value in printing properties with the plain printer.
 void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
-                                                 const char* test_case_name,
+                                                 const char* test_suite_name,
                                                  const TestInfo& test_info) {
   const TestResult& result = *test_info.result();
-  const std::string kTestcase = "testcase";
+  const std::string kTestsuite = "testcase";
+
+  if (test_info.is_in_another_shard()) {
+    return;
+  }
 
   *stream << "    <testcase";
-  OutputXmlAttribute(stream, kTestcase, "name", test_info.name());
+  OutputXmlAttribute(stream, kTestsuite, "name", test_info.name());
 
-  if (test_info.value_param() != NULL) {
-    OutputXmlAttribute(stream, kTestcase, "value_param",
+  if (test_info.value_param() != nullptr) {
+    OutputXmlAttribute(stream, kTestsuite, "value_param",
                        test_info.value_param());
   }
-  if (test_info.type_param() != NULL) {
-    OutputXmlAttribute(stream, kTestcase, "type_param", test_info.type_param());
+  if (test_info.type_param() != nullptr) {
+    OutputXmlAttribute(stream, kTestsuite, "type_param",
+                       test_info.type_param());
+  }
+  if (GTEST_FLAG(list_tests)) {
+    OutputXmlAttribute(stream, kTestsuite, "file", test_info.file());
+    OutputXmlAttribute(stream, kTestsuite, "line",
+                       StreamableToString(test_info.line()));
+    *stream << " />\n";
+    return;
   }
 
-  OutputXmlAttribute(stream, kTestcase, "status",
-                     test_info.should_run() ? "run" : "notrun");
-  OutputXmlAttribute(stream, kTestcase, "time",
+  OutputXmlAttribute(
+      stream, kTestsuite, "status",
+      result.Skipped() ? "skipped" : test_info.should_run() ? "run" : "notrun");
+  OutputXmlAttribute(stream, kTestsuite, "time",
                      FormatTimeInMillisAsSeconds(result.elapsed_time()));
-  OutputXmlAttribute(stream, kTestcase, "classname", test_case_name);
-  *stream << TestPropertiesAsXmlAttributes(result);
+  OutputXmlAttribute(stream, kTestsuite, "classname", test_suite_name);
 
   int failures = 0;
   for (int i = 0; i < result.total_part_count(); ++i) {
@@ -5101,46 +5247,53 @@
       if (++failures == 1) {
         *stream << ">\n";
       }
-      const string location = internal::FormatCompilerIndependentFileLocation(
-          part.file_name(), part.line_number());
-      const string summary = location + "\n" + part.summary();
+      const std::string location =
+          internal::FormatCompilerIndependentFileLocation(part.file_name(),
+                                                          part.line_number());
+      const std::string summary = location + "\n" + part.summary();
       *stream << "      <failure message=\""
               << EscapeXmlAttribute(summary.c_str())
               << "\" type=\"\">";
-      const string detail = location + "\n" + part.message();
+      const std::string detail = location + "\n" + part.message();
       OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());
       *stream << "</failure>\n";
     }
   }
 
-  if (failures == 0)
+  if (failures == 0 && result.test_property_count() == 0) {
     *stream << " />\n";
-  else
+  } else {
+    if (failures == 0) {
+      *stream << ">\n";
+    }
+    OutputXmlTestProperties(stream, result);
     *stream << "    </testcase>\n";
+  }
 }
 
-// Prints an XML representation of a TestCase object
-void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream,
-                                                const TestCase& test_case) {
+// Prints an XML representation of a TestSuite object
+void XmlUnitTestResultPrinter::PrintXmlTestSuite(std::ostream* stream,
+                                                 const TestSuite& test_suite) {
   const std::string kTestsuite = "testsuite";
   *stream << "  <" << kTestsuite;
-  OutputXmlAttribute(stream, kTestsuite, "name", test_case.name());
+  OutputXmlAttribute(stream, kTestsuite, "name", test_suite.name());
   OutputXmlAttribute(stream, kTestsuite, "tests",
-                     StreamableToString(test_case.reportable_test_count()));
-  OutputXmlAttribute(stream, kTestsuite, "failures",
-                     StreamableToString(test_case.failed_test_count()));
-  OutputXmlAttribute(
-      stream, kTestsuite, "disabled",
-      StreamableToString(test_case.reportable_disabled_test_count()));
-  OutputXmlAttribute(stream, kTestsuite, "errors", "0");
-  OutputXmlAttribute(stream, kTestsuite, "time",
-                     FormatTimeInMillisAsSeconds(test_case.elapsed_time()));
-  *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result())
-          << ">\n";
-
-  for (int i = 0; i < test_case.total_test_count(); ++i) {
-    if (test_case.GetTestInfo(i)->is_reportable())
-      OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i));
+                     StreamableToString(test_suite.reportable_test_count()));
+  if (!GTEST_FLAG(list_tests)) {
+    OutputXmlAttribute(stream, kTestsuite, "failures",
+                       StreamableToString(test_suite.failed_test_count()));
+    OutputXmlAttribute(
+        stream, kTestsuite, "disabled",
+        StreamableToString(test_suite.reportable_disabled_test_count()));
+    OutputXmlAttribute(stream, kTestsuite, "errors", "0");
+    OutputXmlAttribute(stream, kTestsuite, "time",
+                       FormatTimeInMillisAsSeconds(test_suite.elapsed_time()));
+    *stream << TestPropertiesAsXmlAttributes(test_suite.ad_hoc_test_result());
+  }
+  *stream << ">\n";
+  for (int i = 0; i < test_suite.total_test_count(); ++i) {
+    if (test_suite.GetTestInfo(i)->is_reportable())
+      OutputXmlTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i));
   }
   *stream << "  </" << kTestsuite << ">\n";
 }
@@ -5171,15 +5324,36 @@
     OutputXmlAttribute(stream, kTestsuites, "random_seed",
                        StreamableToString(unit_test.random_seed()));
   }
-
   *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result());
 
   OutputXmlAttribute(stream, kTestsuites, "name", "AllTests");
   *stream << ">\n";
 
-  for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
-    if (unit_test.GetTestCase(i)->reportable_test_count() > 0)
-      PrintXmlTestCase(stream, *unit_test.GetTestCase(i));
+  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
+    if (unit_test.GetTestSuite(i)->reportable_test_count() > 0)
+      PrintXmlTestSuite(stream, *unit_test.GetTestSuite(i));
+  }
+  *stream << "</" << kTestsuites << ">\n";
+}
+
+void XmlUnitTestResultPrinter::PrintXmlTestsList(
+    std::ostream* stream, const std::vector<TestSuite*>& test_suites) {
+  const std::string kTestsuites = "testsuites";
+
+  *stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+  *stream << "<" << kTestsuites;
+
+  int total_tests = 0;
+  for (auto test_suite : test_suites) {
+    total_tests += test_suite->total_test_count();
+  }
+  OutputXmlAttribute(stream, kTestsuites, "tests",
+                     StreamableToString(total_tests));
+  OutputXmlAttribute(stream, kTestsuites, "name", "AllTests");
+  *stream << ">\n";
+
+  for (auto test_suite : test_suites) {
+    PrintXmlTestSuite(stream, *test_suite);
   }
   *stream << "</" << kTestsuites << ">\n";
 }
@@ -5197,8 +5371,393 @@
   return attributes.GetString();
 }
 
+void XmlUnitTestResultPrinter::OutputXmlTestProperties(
+    std::ostream* stream, const TestResult& result) {
+  const std::string kProperties = "properties";
+  const std::string kProperty = "property";
+
+  if (result.test_property_count() <= 0) {
+    return;
+  }
+
+  *stream << "<" << kProperties << ">\n";
+  for (int i = 0; i < result.test_property_count(); ++i) {
+    const TestProperty& property = result.GetTestProperty(i);
+    *stream << "<" << kProperty;
+    *stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\"";
+    *stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\"";
+    *stream << "/>\n";
+  }
+  *stream << "</" << kProperties << ">\n";
+}
+
 // End XmlUnitTestResultPrinter
 
+// This class generates an JSON output file.
+class JsonUnitTestResultPrinter : public EmptyTestEventListener {
+ public:
+  explicit JsonUnitTestResultPrinter(const char* output_file);
+
+  void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
+
+  // Prints an JSON summary of all unit tests.
+  static void PrintJsonTestList(::std::ostream* stream,
+                                const std::vector<TestSuite*>& test_suites);
+
+ private:
+  // Returns an JSON-escaped copy of the input string str.
+  static std::string EscapeJson(const std::string& str);
+
+  //// Verifies that the given attribute belongs to the given element and
+  //// streams the attribute as JSON.
+  static void OutputJsonKey(std::ostream* stream,
+                            const std::string& element_name,
+                            const std::string& name,
+                            const std::string& value,
+                            const std::string& indent,
+                            bool comma = true);
+  static void OutputJsonKey(std::ostream* stream,
+                            const std::string& element_name,
+                            const std::string& name,
+                            int value,
+                            const std::string& indent,
+                            bool comma = true);
+
+  // Streams a JSON representation of a TestInfo object.
+  static void OutputJsonTestInfo(::std::ostream* stream,
+                                 const char* test_suite_name,
+                                 const TestInfo& test_info);
+
+  // Prints a JSON representation of a TestSuite object
+  static void PrintJsonTestSuite(::std::ostream* stream,
+                                 const TestSuite& test_suite);
+
+  // Prints a JSON summary of unit_test to output stream out.
+  static void PrintJsonUnitTest(::std::ostream* stream,
+                                const UnitTest& unit_test);
+
+  // Produces a string representing the test properties in a result as
+  // a JSON dictionary.
+  static std::string TestPropertiesAsJson(const TestResult& result,
+                                          const std::string& indent);
+
+  // The output file.
+  const std::string output_file_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(JsonUnitTestResultPrinter);
+};
+
+// Creates a new JsonUnitTestResultPrinter.
+JsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file)
+    : output_file_(output_file) {
+  if (output_file_.empty()) {
+    GTEST_LOG_(FATAL) << "JSON output file may not be null";
+  }
+}
+
+void JsonUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
+                                                  int /*iteration*/) {
+  FILE* jsonout = OpenFileForWriting(output_file_);
+  std::stringstream stream;
+  PrintJsonUnitTest(&stream, unit_test);
+  fprintf(jsonout, "%s", StringStreamToString(&stream).c_str());
+  fclose(jsonout);
+}
+
+// Returns an JSON-escaped copy of the input string str.
+std::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) {
+  Message m;
+
+  for (size_t i = 0; i < str.size(); ++i) {
+    const char ch = str[i];
+    switch (ch) {
+      case '\\':
+      case '"':
+      case '/':
+        m << '\\' << ch;
+        break;
+      case '\b':
+        m << "\\b";
+        break;
+      case '\t':
+        m << "\\t";
+        break;
+      case '\n':
+        m << "\\n";
+        break;
+      case '\f':
+        m << "\\f";
+        break;
+      case '\r':
+        m << "\\r";
+        break;
+      default:
+        if (ch < ' ') {
+          m << "\\u00" << String::FormatByte(static_cast<unsigned char>(ch));
+        } else {
+          m << ch;
+        }
+        break;
+    }
+  }
+
+  return m.GetString();
+}
+
+// The following routines generate an JSON representation of a UnitTest
+// object.
+
+// Formats the given time in milliseconds as seconds.
+static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) {
+  ::std::stringstream ss;
+  ss << (static_cast<double>(ms) * 1e-3) << "s";
+  return ss.str();
+}
+
+// Converts the given epoch time in milliseconds to a date string in the
+// RFC3339 format, without the timezone information.
+static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) {
+  struct tm time_struct;
+  if (!PortableLocaltime(static_cast<time_t>(ms / 1000), &time_struct))
+    return "";
+  // YYYY-MM-DDThh:mm:ss
+  return StreamableToString(time_struct.tm_year + 1900) + "-" +
+      String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" +
+      String::FormatIntWidth2(time_struct.tm_mday) + "T" +
+      String::FormatIntWidth2(time_struct.tm_hour) + ":" +
+      String::FormatIntWidth2(time_struct.tm_min) + ":" +
+      String::FormatIntWidth2(time_struct.tm_sec) + "Z";
+}
+
+static inline std::string Indent(int width) {
+  return std::string(width, ' ');
+}
+
+void JsonUnitTestResultPrinter::OutputJsonKey(
+    std::ostream* stream,
+    const std::string& element_name,
+    const std::string& name,
+    const std::string& value,
+    const std::string& indent,
+    bool comma) {
+  const std::vector<std::string>& allowed_names =
+      GetReservedAttributesForElement(element_name);
+
+  GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=
+                   allowed_names.end())
+      << "Key \"" << name << "\" is not allowed for value \"" << element_name
+      << "\".";
+
+  *stream << indent << "\"" << name << "\": \"" << EscapeJson(value) << "\"";
+  if (comma)
+    *stream << ",\n";
+}
+
+void JsonUnitTestResultPrinter::OutputJsonKey(
+    std::ostream* stream,
+    const std::string& element_name,
+    const std::string& name,
+    int value,
+    const std::string& indent,
+    bool comma) {
+  const std::vector<std::string>& allowed_names =
+      GetReservedAttributesForElement(element_name);
+
+  GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=
+                   allowed_names.end())
+      << "Key \"" << name << "\" is not allowed for value \"" << element_name
+      << "\".";
+
+  *stream << indent << "\"" << name << "\": " << StreamableToString(value);
+  if (comma)
+    *stream << ",\n";
+}
+
+// Prints a JSON representation of a TestInfo object.
+void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream,
+                                                   const char* test_suite_name,
+                                                   const TestInfo& test_info) {
+  const TestResult& result = *test_info.result();
+  const std::string kTestsuite = "testcase";
+  const std::string kIndent = Indent(10);
+
+  *stream << Indent(8) << "{\n";
+  OutputJsonKey(stream, kTestsuite, "name", test_info.name(), kIndent);
+
+  if (test_info.value_param() != nullptr) {
+    OutputJsonKey(stream, kTestsuite, "value_param", test_info.value_param(),
+                  kIndent);
+  }
+  if (test_info.type_param() != nullptr) {
+    OutputJsonKey(stream, kTestsuite, "type_param", test_info.type_param(),
+                  kIndent);
+  }
+  if (GTEST_FLAG(list_tests)) {
+    OutputJsonKey(stream, kTestsuite, "file", test_info.file(), kIndent);
+    OutputJsonKey(stream, kTestsuite, "line", test_info.line(), kIndent, false);
+    *stream << "\n" << Indent(8) << "}";
+    return;
+  }
+
+  OutputJsonKey(
+      stream, kTestsuite, "status",
+      result.Skipped() ? "SKIPPED" : test_info.should_run() ? "RUN" : "NOTRUN",
+      kIndent);
+  OutputJsonKey(stream, kTestsuite, "time",
+                FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent);
+  OutputJsonKey(stream, kTestsuite, "classname", test_suite_name, kIndent,
+                false);
+  *stream << TestPropertiesAsJson(result, kIndent);
+
+  int failures = 0;
+  for (int i = 0; i < result.total_part_count(); ++i) {
+    const TestPartResult& part = result.GetTestPartResult(i);
+    if (part.failed()) {
+      *stream << ",\n";
+      if (++failures == 1) {
+        *stream << kIndent << "\"" << "failures" << "\": [\n";
+      }
+      const std::string location =
+          internal::FormatCompilerIndependentFileLocation(part.file_name(),
+                                                          part.line_number());
+      const std::string message = EscapeJson(location + "\n" + part.message());
+      *stream << kIndent << "  {\n"
+              << kIndent << "    \"failure\": \"" << message << "\",\n"
+              << kIndent << "    \"type\": \"\"\n"
+              << kIndent << "  }";
+    }
+  }
+
+  if (failures > 0)
+    *stream << "\n" << kIndent << "]";
+  *stream << "\n" << Indent(8) << "}";
+}
+
+// Prints an JSON representation of a TestSuite object
+void JsonUnitTestResultPrinter::PrintJsonTestSuite(
+    std::ostream* stream, const TestSuite& test_suite) {
+  const std::string kTestsuite = "testsuite";
+  const std::string kIndent = Indent(6);
+
+  *stream << Indent(4) << "{\n";
+  OutputJsonKey(stream, kTestsuite, "name", test_suite.name(), kIndent);
+  OutputJsonKey(stream, kTestsuite, "tests", test_suite.reportable_test_count(),
+                kIndent);
+  if (!GTEST_FLAG(list_tests)) {
+    OutputJsonKey(stream, kTestsuite, "failures",
+                  test_suite.failed_test_count(), kIndent);
+    OutputJsonKey(stream, kTestsuite, "disabled",
+                  test_suite.reportable_disabled_test_count(), kIndent);
+    OutputJsonKey(stream, kTestsuite, "errors", 0, kIndent);
+    OutputJsonKey(stream, kTestsuite, "time",
+                  FormatTimeInMillisAsDuration(test_suite.elapsed_time()),
+                  kIndent, false);
+    *stream << TestPropertiesAsJson(test_suite.ad_hoc_test_result(), kIndent)
+            << ",\n";
+  }
+
+  *stream << kIndent << "\"" << kTestsuite << "\": [\n";
+
+  bool comma = false;
+  for (int i = 0; i < test_suite.total_test_count(); ++i) {
+    if (test_suite.GetTestInfo(i)->is_reportable()) {
+      if (comma) {
+        *stream << ",\n";
+      } else {
+        comma = true;
+      }
+      OutputJsonTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i));
+    }
+  }
+  *stream << "\n" << kIndent << "]\n" << Indent(4) << "}";
+}
+
+// Prints a JSON summary of unit_test to output stream out.
+void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,
+                                                  const UnitTest& unit_test) {
+  const std::string kTestsuites = "testsuites";
+  const std::string kIndent = Indent(2);
+  *stream << "{\n";
+
+  OutputJsonKey(stream, kTestsuites, "tests", unit_test.reportable_test_count(),
+                kIndent);
+  OutputJsonKey(stream, kTestsuites, "failures", unit_test.failed_test_count(),
+                kIndent);
+  OutputJsonKey(stream, kTestsuites, "disabled",
+                unit_test.reportable_disabled_test_count(), kIndent);
+  OutputJsonKey(stream, kTestsuites, "errors", 0, kIndent);
+  if (GTEST_FLAG(shuffle)) {
+    OutputJsonKey(stream, kTestsuites, "random_seed", unit_test.random_seed(),
+                  kIndent);
+  }
+  OutputJsonKey(stream, kTestsuites, "timestamp",
+                FormatEpochTimeInMillisAsRFC3339(unit_test.start_timestamp()),
+                kIndent);
+  OutputJsonKey(stream, kTestsuites, "time",
+                FormatTimeInMillisAsDuration(unit_test.elapsed_time()), kIndent,
+                false);
+
+  *stream << TestPropertiesAsJson(unit_test.ad_hoc_test_result(), kIndent)
+          << ",\n";
+
+  OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent);
+  *stream << kIndent << "\"" << kTestsuites << "\": [\n";
+
+  bool comma = false;
+  for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
+    if (unit_test.GetTestSuite(i)->reportable_test_count() > 0) {
+      if (comma) {
+        *stream << ",\n";
+      } else {
+        comma = true;
+      }
+      PrintJsonTestSuite(stream, *unit_test.GetTestSuite(i));
+    }
+  }
+
+  *stream << "\n" << kIndent << "]\n" << "}\n";
+}
+
+void JsonUnitTestResultPrinter::PrintJsonTestList(
+    std::ostream* stream, const std::vector<TestSuite*>& test_suites) {
+  const std::string kTestsuites = "testsuites";
+  const std::string kIndent = Indent(2);
+  *stream << "{\n";
+  int total_tests = 0;
+  for (auto test_suite : test_suites) {
+    total_tests += test_suite->total_test_count();
+  }
+  OutputJsonKey(stream, kTestsuites, "tests", total_tests, kIndent);
+
+  OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent);
+  *stream << kIndent << "\"" << kTestsuites << "\": [\n";
+
+  for (size_t i = 0; i < test_suites.size(); ++i) {
+    if (i != 0) {
+      *stream << ",\n";
+    }
+    PrintJsonTestSuite(stream, *test_suites[i]);
+  }
+
+  *stream << "\n"
+          << kIndent << "]\n"
+          << "}\n";
+}
+// Produces a string representing the test properties in a result as
+// a JSON dictionary.
+std::string JsonUnitTestResultPrinter::TestPropertiesAsJson(
+    const TestResult& result, const std::string& indent) {
+  Message attributes;
+  for (int i = 0; i < result.test_property_count(); ++i) {
+    const TestProperty& property = result.GetTestProperty(i);
+    attributes << ",\n" << indent << "\"" << property.key() << "\": "
+               << "\"" << EscapeJson(property.value()) << "\"";
+  }
+  return attributes.GetString();
+}
+
+// End JsonUnitTestResultPrinter
+
 #if GTEST_CAN_STREAM_RESULTS_
 
 // Checks if str contains '=', '&', '%' or '\n' characters. If yes,
@@ -5206,8 +5765,8 @@
 // example, replaces "=" with "%3D".  This algorithm is O(strlen(str))
 // in both time and space -- important as the input str may contain an
 // arbitrarily long test failure message and stack trace.
-string StreamingListener::UrlEncode(const char* str) {
-  string result;
+std::string StreamingListener::UrlEncode(const char* str) {
+  std::string result;
   result.reserve(strlen(str) + 1);
   for (char ch = *str; ch != '\0'; ch = *++str) {
     switch (ch) {
@@ -5233,7 +5792,7 @@
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = AF_UNSPEC;    // To allow both IPv4 and IPv6 addresses.
   hints.ai_socktype = SOCK_STREAM;
-  addrinfo* servinfo = NULL;
+  addrinfo* servinfo = nullptr;
 
   // Use the getaddrinfo() to get a linked list of IP addresses for
   // the given host name.
@@ -5245,7 +5804,7 @@
   }
 
   // Loop through all the results and connect to the first we can.
-  for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL;
+  for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != nullptr;
        cur_addr = cur_addr->ai_next) {
     sockfd_ = socket(
         cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol);
@@ -5269,47 +5828,82 @@
 // End of class Streaming Listener
 #endif  // GTEST_CAN_STREAM_RESULTS__
 
-// Class ScopedTrace
-
-// Pushes the given source file location and message onto a per-thread
-// trace stack maintained by Google Test.
-ScopedTrace::ScopedTrace(const char* file, int line, const Message& message)
-    GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
-  TraceInfo trace;
-  trace.file = file;
-  trace.line = line;
-  trace.message = message.GetString();
-
-  UnitTest::GetInstance()->PushGTestTrace(trace);
-}
-
-// Pops the info pushed by the c'tor.
-ScopedTrace::~ScopedTrace()
-    GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
-  UnitTest::GetInstance()->PopGTestTrace();
-}
-
-
 // class OsStackTraceGetter
 
 const char* const OsStackTraceGetterInterface::kElidedFramesMarker =
     "... " GTEST_NAME_ " internal frames ...";
 
-string OsStackTraceGetter::CurrentStackTrace(int /*max_depth*/,
-                                             int /*skip_count*/) {
+std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count)
+    GTEST_LOCK_EXCLUDED_(mutex_) {
+#if GTEST_HAS_ABSL
+  std::string result;
+
+  if (max_depth <= 0) {
+    return result;
+  }
+
+  max_depth = std::min(max_depth, kMaxStackTraceDepth);
+
+  std::vector<void*> raw_stack(max_depth);
+  // Skips the frames requested by the caller, plus this function.
+  const int raw_stack_size =
+      absl::GetStackTrace(&raw_stack[0], max_depth, skip_count + 1);
+
+  void* caller_frame = nullptr;
+  {
+    MutexLock lock(&mutex_);
+    caller_frame = caller_frame_;
+  }
+
+  for (int i = 0; i < raw_stack_size; ++i) {
+    if (raw_stack[i] == caller_frame &&
+        !GTEST_FLAG(show_internal_stack_frames)) {
+      // Add a marker to the trace and stop adding frames.
+      absl::StrAppend(&result, kElidedFramesMarker, "\n");
+      break;
+    }
+
+    char tmp[1024];
+    const char* symbol = "(unknown)";
+    if (absl::Symbolize(raw_stack[i], tmp, sizeof(tmp))) {
+      symbol = tmp;
+    }
+
+    char line[1024];
+    snprintf(line, sizeof(line), "  %p: %s\n", raw_stack[i], symbol);
+    result += line;
+  }
+
+  return result;
+
+#else  // !GTEST_HAS_ABSL
+  static_cast<void>(max_depth);
+  static_cast<void>(skip_count);
   return "";
+#endif  // GTEST_HAS_ABSL
 }
 
-void OsStackTraceGetter::UponLeavingGTest() {}
+void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) {
+#if GTEST_HAS_ABSL
+  void* caller_frame = nullptr;
+  if (absl::GetStackTrace(&caller_frame, 1, 3) <= 0) {
+    caller_frame = nullptr;
+  }
+
+  MutexLock lock(&mutex_);
+  caller_frame_ = caller_frame;
+#endif  // GTEST_HAS_ABSL
+}
 
 // A helper class that creates the premature-exit file in its
 // constructor and deletes the file in its destructor.
 class ScopedPrematureExitFile {
  public:
   explicit ScopedPrematureExitFile(const char* premature_exit_filepath)
-      : premature_exit_filepath_(premature_exit_filepath) {
+      : premature_exit_filepath_(premature_exit_filepath ?
+                                 premature_exit_filepath : "") {
     // If a path to the premature-exit file is specified...
-    if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') {
+    if (!premature_exit_filepath_.empty()) {
       // create the file with a single "0" character in it.  I/O
       // errors are ignored as there's nothing better we can do and we
       // don't want to fail the test because of this.
@@ -5320,13 +5914,18 @@
   }
 
   ~ScopedPrematureExitFile() {
-    if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') {
-      remove(premature_exit_filepath_);
+    if (!premature_exit_filepath_.empty()) {
+      int retval = remove(premature_exit_filepath_.c_str());
+      if (retval) {
+        GTEST_LOG_(ERROR) << "Failed to remove premature exit filepath \""
+                          << premature_exit_filepath_ << "\" with error "
+                          << retval;
+      }
     }
   }
 
  private:
-  const char* const premature_exit_filepath_;
+  const std::string premature_exit_filepath_;
 
   GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile);
 };
@@ -5337,9 +5936,8 @@
 
 TestEventListeners::TestEventListeners()
     : repeater_(new internal::TestEventRepeater()),
-      default_result_printer_(NULL),
-      default_xml_generator_(NULL) {
-}
+      default_result_printer_(nullptr),
+      default_xml_generator_(nullptr) {}
 
 TestEventListeners::~TestEventListeners() { delete repeater_; }
 
@@ -5356,9 +5954,9 @@
 // NULL if the listener is not found in the list.
 TestEventListener* TestEventListeners::Release(TestEventListener* listener) {
   if (listener == default_result_printer_)
-    default_result_printer_ = NULL;
+    default_result_printer_ = nullptr;
   else if (listener == default_xml_generator_)
-    default_xml_generator_ = NULL;
+    default_xml_generator_ = nullptr;
   return repeater_->Release(listener);
 }
 
@@ -5377,8 +5975,7 @@
     // list.
     delete Release(default_result_printer_);
     default_result_printer_ = listener;
-    if (listener != NULL)
-      Append(listener);
+    if (listener != nullptr) Append(listener);
   }
 }
 
@@ -5393,8 +5990,7 @@
     // list.
     delete Release(default_xml_generator_);
     default_xml_generator_ = listener;
-    if (listener != NULL)
-      Append(listener);
+    if (listener != nullptr) Append(listener);
   }
 }
 
@@ -5418,52 +6014,66 @@
 // call this before main() starts, from which point on the return
 // value will never change.
 UnitTest* UnitTest::GetInstance() {
-  // When compiled with MSVC 7.1 in optimized mode, destroying the
-  // UnitTest object upon exiting the program messes up the exit code,
-  // causing successful tests to appear failed.  We have to use a
-  // different implementation in this case to bypass the compiler bug.
-  // This implementation makes the compiler happy, at the cost of
-  // leaking the UnitTest object.
-
   // CodeGear C++Builder insists on a public destructor for the
   // default implementation.  Use this implementation to keep good OO
   // design with private destructor.
 
-#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+#if defined(__BORLANDC__)
   static UnitTest* const instance = new UnitTest;
   return instance;
 #else
   static UnitTest instance;
   return &instance;
-#endif  // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+#endif  // defined(__BORLANDC__)
 }
 
-// Gets the number of successful test cases.
-int UnitTest::successful_test_case_count() const {
-  return impl()->successful_test_case_count();
+// Gets the number of successful test suites.
+int UnitTest::successful_test_suite_count() const {
+  return impl()->successful_test_suite_count();
 }
 
-// Gets the number of failed test cases.
-int UnitTest::failed_test_case_count() const {
-  return impl()->failed_test_case_count();
+// Gets the number of failed test suites.
+int UnitTest::failed_test_suite_count() const {
+  return impl()->failed_test_suite_count();
 }
 
-// Gets the number of all test cases.
-int UnitTest::total_test_case_count() const {
-  return impl()->total_test_case_count();
+// Gets the number of all test suites.
+int UnitTest::total_test_suite_count() const {
+  return impl()->total_test_suite_count();
 }
 
-// Gets the number of all test cases that contain at least one test
+// Gets the number of all test suites that contain at least one test
 // that should run.
-int UnitTest::test_case_to_run_count() const {
-  return impl()->test_case_to_run_count();
+int UnitTest::test_suite_to_run_count() const {
+  return impl()->test_suite_to_run_count();
 }
 
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+int UnitTest::successful_test_case_count() const {
+  return impl()->successful_test_suite_count();
+}
+int UnitTest::failed_test_case_count() const {
+  return impl()->failed_test_suite_count();
+}
+int UnitTest::total_test_case_count() const {
+  return impl()->total_test_suite_count();
+}
+int UnitTest::test_case_to_run_count() const {
+  return impl()->test_suite_to_run_count();
+}
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
 // Gets the number of successful tests.
 int UnitTest::successful_test_count() const {
   return impl()->successful_test_count();
 }
 
+// Gets the number of skipped tests.
+int UnitTest::skipped_test_count() const {
+  return impl()->skipped_test_count();
+}
+
 // Gets the number of failed tests.
 int UnitTest::failed_test_count() const { return impl()->failed_test_count(); }
 
@@ -5499,29 +6109,36 @@
   return impl()->elapsed_time();
 }
 
-// Returns true iff the unit test passed (i.e. all test cases passed).
+// Returns true iff the unit test passed (i.e. all test suites passed).
 bool UnitTest::Passed() const { return impl()->Passed(); }
 
-// Returns true iff the unit test failed (i.e. some test case failed
+// Returns true iff the unit test failed (i.e. some test suite failed
 // or something outside of all tests failed).
 bool UnitTest::Failed() const { return impl()->Failed(); }
 
-// Gets the i-th test case among all the test cases. i can range from 0 to
-// total_test_case_count() - 1. If i is not in that range, returns NULL.
+// Gets the i-th test suite among all the test suites. i can range from 0 to
+// total_test_suite_count() - 1. If i is not in that range, returns NULL.
+const TestSuite* UnitTest::GetTestSuite(int i) const {
+  return impl()->GetTestSuite(i);
+}
+
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 const TestCase* UnitTest::GetTestCase(int i) const {
   return impl()->GetTestCase(i);
 }
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
 // Returns the TestResult containing information on test failures and
-// properties logged outside of individual test cases.
+// properties logged outside of individual test suites.
 const TestResult& UnitTest::ad_hoc_test_result() const {
   return *impl()->ad_hoc_test_result();
 }
 
-// Gets the i-th test case among all the test cases. i can range from 0 to
-// total_test_case_count() - 1. If i is not in that range, returns NULL.
-TestCase* UnitTest::GetMutableTestCase(int i) {
-  return impl()->GetMutableTestCase(i);
+// Gets the i-th test suite among all the test suites. i can range from 0 to
+// total_test_suite_count() - 1. If i is not in that range, returns NULL.
+TestSuite* UnitTest::GetMutableTestSuite(int i) {
+  return impl()->GetMutableSuiteCase(i);
 }
 
 // Returns the list of event listeners that can be used to track events
@@ -5541,8 +6158,8 @@
 // We don't protect this under mutex_, as we only support calling it
 // from the main thread.
 Environment* UnitTest::AddEnvironment(Environment* env) {
-  if (env == NULL) {
-    return NULL;
+  if (env == nullptr) {
+    return nullptr;
   }
 
   impl_->environments().push_back(env);
@@ -5574,17 +6191,17 @@
     }
   }
 
-  if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) {
+  if (os_stack_trace.c_str() != nullptr && !os_stack_trace.empty()) {
     msg << internal::kStackTraceMarker << os_stack_trace;
   }
 
-  const TestPartResult result =
-    TestPartResult(result_type, file_name, line_number,
-                   msg.GetString().c_str());
+  const TestPartResult result = TestPartResult(
+      result_type, file_name, line_number, msg.GetString().c_str());
   impl_->GetTestPartResultReporterForCurrentThread()->
       ReportTestPartResult(result);
 
-  if (result_type != TestPartResult::kSuccess) {
+  if (result_type != TestPartResult::kSuccess &&
+      result_type != TestPartResult::kSkip) {
     // gtest_break_on_failure takes precedence over
     // gtest_throw_on_failure.  This allows a user to set the latter
     // in the code (perhaps in order to use Google Test assertions
@@ -5596,12 +6213,16 @@
       // when a failure happens and both the --gtest_break_on_failure and
       // the --gtest_catch_exceptions flags are specified.
       DebugBreak();
+#elif (!defined(__native_client__)) &&            \
+    ((defined(__clang__) || defined(__GNUC__)) && \
+     (defined(__x86_64__) || defined(__i386__)))
+      // with clang/gcc we can achieve the same effect on x86 by invoking int3
+      asm("int3");
 #else
-      // Dereference NULL through a volatile pointer to prevent the compiler
+      // Dereference nullptr through a volatile pointer to prevent the compiler
       // from removing. We use this rather than abort() or __builtin_trap() for
-      // portability: Symbian doesn't implement abort() well, and some debuggers
-      // don't correctly trap abort().
-      *static_cast<volatile int*>(NULL) = 1;
+      // portability: some debuggers don't correctly trap abort().
+      *static_cast<volatile int*>(nullptr) = 1;
 #endif  // GTEST_OS_WINDOWS
     } else if (GTEST_FLAG(throw_on_failure)) {
 #if GTEST_HAS_EXCEPTIONS
@@ -5616,8 +6237,8 @@
 }
 
 // Adds a TestProperty to the current TestResult object when invoked from
-// inside a test, to current TestCase's ad_hoc_test_result_ when invoked
-// from SetUpTestCase or TearDownTestCase, or to the global property set
+// inside a test, to current TestSuite's ad_hoc_test_result_ when invoked
+// from SetUpTestSuite or TearDownTestSuite, or to the global property set
 // when invoked elsewhere.  If the result already contains a property with
 // the same key, the value will be updated.
 void UnitTest::RecordProperty(const std::string& key,
@@ -5656,14 +6277,15 @@
   // that understands the premature-exit-file protocol to report the
   // test as having failed.
   const internal::ScopedPrematureExitFile premature_exit_file(
-      in_death_test_child_process ?
-      NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE"));
+      in_death_test_child_process
+          ? nullptr
+          : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE"));
 
   // Captures the value of GTEST_FLAG(catch_exceptions).  This value will be
   // used for the duration of the program.
   impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions));
 
-#if GTEST_HAS_SEH
+#if GTEST_OS_WINDOWS
   // Either the user wants Google Test to catch exceptions thrown by the
   // tests or this is executing in the context of death test child
   // process. In either case the user does not want to see pop-up dialogs
@@ -5682,25 +6304,19 @@
     _set_error_mode(_OUT_TO_STDERR);
 # endif
 
-# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE
+# if defined(_MSC_VER) && !GTEST_OS_WINDOWS_MOBILE
     // In the debug version, Visual Studio pops up a separate dialog
     // offering a choice to debug the aborted program. We need to suppress
     // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement
     // executed. Google Test will notify the user of any unexpected
     // failure via stderr.
-    //
-    // VC++ doesn't define _set_abort_behavior() prior to the version 8.0.
-    // Users of prior VC versions shall suffer the agony and pain of
-    // clicking through the countless debug dialogs.
-    // TODO(vladl@google.com): find a way to suppress the abort dialog() in the
-    // debug mode when compiled with VC 7.1 or lower.
     if (!GTEST_FLAG(break_on_failure))
       _set_abort_behavior(
           0x0,                                    // Clear the following flags:
           _WRITE_ABORT_MSG | _CALL_REPORTFAULT);  // pop-up window, core dump.
 # endif
   }
-#endif  // GTEST_HAS_SEH
+#endif  // GTEST_OS_WINDOWS
 
   return internal::HandleExceptionsInMethodIfSupported(
       impl(),
@@ -5714,13 +6330,22 @@
   return impl_->original_working_dir_.c_str();
 }
 
-// Returns the TestCase object for the test that's currently running,
+// Returns the TestSuite object for the test that's currently running,
 // or NULL if no test is running.
+const TestSuite* UnitTest::current_test_suite() const
+    GTEST_LOCK_EXCLUDED_(mutex_) {
+  internal::MutexLock lock(&mutex_);
+  return impl_->current_test_suite();
+}
+
+// Legacy API is still available but deprecated
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 const TestCase* UnitTest::current_test_case() const
     GTEST_LOCK_EXCLUDED_(mutex_) {
   internal::MutexLock lock(&mutex_);
-  return impl_->current_test_case();
+  return impl_->current_test_suite();
 }
+#endif
 
 // Returns the TestInfo object for the test that's currently running,
 // or NULL if no test is running.
@@ -5733,15 +6358,12 @@
 // Returns the random seed used at the start of the current test run.
 int UnitTest::random_seed() const { return impl_->random_seed(); }
 
-#if GTEST_HAS_PARAM_TEST
-// Returns ParameterizedTestCaseRegistry object used to keep track of
+// Returns ParameterizedTestSuiteRegistry object used to keep track of
 // value-parameterized tests and instantiate and register them.
-internal::ParameterizedTestCaseRegistry&
-    UnitTest::parameterized_test_registry()
-        GTEST_LOCK_EXCLUDED_(mutex_) {
+internal::ParameterizedTestSuiteRegistry&
+UnitTest::parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_) {
   return impl_->parameterized_test_registry();
 }
-#endif  // GTEST_HAS_PARAM_TEST
 
 // Creates an empty UnitTest.
 UnitTest::UnitTest() {
@@ -5773,25 +6395,22 @@
 UnitTestImpl::UnitTestImpl(UnitTest* parent)
     : parent_(parent),
       GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */)
-      default_global_test_part_result_reporter_(this),
+          default_global_test_part_result_reporter_(this),
       default_per_thread_test_part_result_reporter_(this),
-      GTEST_DISABLE_MSC_WARNINGS_POP_()
-      global_test_part_result_repoter_(
+      GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_repoter_(
           &default_global_test_part_result_reporter_),
       per_thread_test_part_result_reporter_(
           &default_per_thread_test_part_result_reporter_),
-#if GTEST_HAS_PARAM_TEST
       parameterized_test_registry_(),
       parameterized_tests_registered_(false),
-#endif  // GTEST_HAS_PARAM_TEST
-      last_death_test_case_(-1),
-      current_test_case_(NULL),
-      current_test_info_(NULL),
+      last_death_test_suite_(-1),
+      current_test_suite_(nullptr),
+      current_test_info_(nullptr),
       ad_hoc_test_result_(),
-      os_stack_trace_getter_(NULL),
+      os_stack_trace_getter_(nullptr),
       post_flag_parse_init_performed_(false),
       random_seed_(0),  // Will be overridden by the flag before first use.
-      random_(0),  // Will be reseeded before first use.
+      random_(0),       // Will be reseeded before first use.
       start_timestamp_(0),
       elapsed_time_(0),
 #if GTEST_HAS_DEATH_TEST
@@ -5803,8 +6422,8 @@
 }
 
 UnitTestImpl::~UnitTestImpl() {
-  // Deletes every TestCase.
-  ForEach(test_cases_, internal::Delete<TestCase>);
+  // Deletes every TestSuite.
+  ForEach(test_suites_, internal::Delete<TestSuite>);
 
   // Deletes every Environment.
   ForEach(environments_, internal::Delete<Environment>);
@@ -5813,20 +6432,20 @@
 }
 
 // Adds a TestProperty to the current TestResult object when invoked in a
-// context of a test, to current test case's ad_hoc_test_result when invoke
-// from SetUpTestCase/TearDownTestCase, or to the global property set
+// context of a test, to current test suite's ad_hoc_test_result when invoke
+// from SetUpTestSuite/TearDownTestSuite, or to the global property set
 // otherwise.  If the result already contains a property with the same key,
 // the value will be updated.
 void UnitTestImpl::RecordProperty(const TestProperty& test_property) {
   std::string xml_element;
   TestResult* test_result;  // TestResult appropriate for property recording.
 
-  if (current_test_info_ != NULL) {
+  if (current_test_info_ != nullptr) {
     xml_element = "testcase";
     test_result = &(current_test_info_->result_);
-  } else if (current_test_case_ != NULL) {
+  } else if (current_test_suite_ != nullptr) {
     xml_element = "testsuite";
-    test_result = &(current_test_case_->ad_hoc_test_result_);
+    test_result = &(current_test_suite_->ad_hoc_test_result_);
   } else {
     xml_element = "testsuites";
     test_result = &ad_hoc_test_result_;
@@ -5838,7 +6457,7 @@
 // Disables event forwarding if the control is currently in a death test
 // subprocess. Must not be called before InitGoogleTest.
 void UnitTestImpl::SuppressTestEventsIfInSubprocess() {
-  if (internal_run_death_test_flag_.get() != NULL)
+  if (internal_run_death_test_flag_.get() != nullptr)
     listeners()->SuppressEventForwarding();
 }
 #endif  // GTEST_HAS_DEATH_TEST
@@ -5850,10 +6469,12 @@
   if (output_format == "xml") {
     listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
         UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
+  } else if (output_format == "json") {
+    listeners()->SetDefaultXmlGenerator(new JsonUnitTestResultPrinter(
+        UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
   } else if (output_format != "") {
-    printf("WARNING: unrecognized output format \"%s\" ignored.\n",
-           output_format.c_str());
-    fflush(stdout);
+    GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \""
+                        << output_format << "\" ignored.";
   }
 }
 
@@ -5868,9 +6489,8 @@
       listeners()->Append(new StreamingListener(target.substr(0, pos),
                                                 target.substr(pos+1)));
     } else {
-      printf("WARNING: unrecognized streaming target \"%s\" ignored.\n",
-             target.c_str());
-      fflush(stdout);
+      GTEST_LOG_(WARNING) << "unrecognized streaming target \"" << target
+                          << "\" ignored.";
     }
   }
 }
@@ -5909,77 +6529,83 @@
     // Configures listeners for streaming test results to the specified server.
     ConfigureStreamingOutput();
 #endif  // GTEST_CAN_STREAM_RESULTS_
+
+#if GTEST_HAS_ABSL
+    if (GTEST_FLAG(install_failure_signal_handler)) {
+      absl::FailureSignalHandlerOptions options;
+      absl::InstallFailureSignalHandler(options);
+    }
+#endif  // GTEST_HAS_ABSL
   }
 }
 
-// A predicate that checks the name of a TestCase against a known
+// A predicate that checks the name of a TestSuite against a known
 // value.
 //
 // This is used for implementation of the UnitTest class only.  We put
 // it in the anonymous namespace to prevent polluting the outer
 // namespace.
 //
-// TestCaseNameIs is copyable.
-class TestCaseNameIs {
+// TestSuiteNameIs is copyable.
+class TestSuiteNameIs {
  public:
   // Constructor.
-  explicit TestCaseNameIs(const std::string& name)
-      : name_(name) {}
+  explicit TestSuiteNameIs(const std::string& name) : name_(name) {}
 
-  // Returns true iff the name of test_case matches name_.
-  bool operator()(const TestCase* test_case) const {
-    return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0;
+  // Returns true iff the name of test_suite matches name_.
+  bool operator()(const TestSuite* test_suite) const {
+    return test_suite != nullptr &&
+           strcmp(test_suite->name(), name_.c_str()) == 0;
   }
 
  private:
   std::string name_;
 };
 
-// Finds and returns a TestCase with the given name.  If one doesn't
+// Finds and returns a TestSuite with the given name.  If one doesn't
 // exist, creates one and returns it.  It's the CALLER'S
 // RESPONSIBILITY to ensure that this function is only called WHEN THE
 // TESTS ARE NOT SHUFFLED.
 //
 // Arguments:
 //
-//   test_case_name: name of the test case
-//   type_param:     the name of the test case's type parameter, or NULL if
-//                   this is not a typed or a type-parameterized test case.
-//   set_up_tc:      pointer to the function that sets up the test case
-//   tear_down_tc:   pointer to the function that tears down the test case
-TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
-                                    const char* type_param,
-                                    Test::SetUpTestCaseFunc set_up_tc,
-                                    Test::TearDownTestCaseFunc tear_down_tc) {
-  // Can we find a TestCase with the given name?
-  const std::vector<TestCase*>::const_iterator test_case =
-      std::find_if(test_cases_.begin(), test_cases_.end(),
-                   TestCaseNameIs(test_case_name));
+//   test_suite_name: name of the test suite
+//   type_param:     the name of the test suite's type parameter, or NULL if
+//                   this is not a typed or a type-parameterized test suite.
+//   set_up_tc:      pointer to the function that sets up the test suite
+//   tear_down_tc:   pointer to the function that tears down the test suite
+TestSuite* UnitTestImpl::GetTestSuite(
+    const char* test_suite_name, const char* type_param,
+    internal::SetUpTestSuiteFunc set_up_tc,
+    internal::TearDownTestSuiteFunc tear_down_tc) {
+  // Can we find a TestSuite with the given name?
+  const auto test_suite =
+      std::find_if(test_suites_.rbegin(), test_suites_.rend(),
+                   TestSuiteNameIs(test_suite_name));
 
-  if (test_case != test_cases_.end())
-    return *test_case;
+  if (test_suite != test_suites_.rend()) return *test_suite;
 
   // No.  Let's create one.
-  TestCase* const new_test_case =
-      new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc);
+  auto* const new_test_suite =
+      new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc);
 
-  // Is this a death test case?
-  if (internal::UnitTestOptions::MatchesFilter(test_case_name,
-                                               kDeathTestCaseFilter)) {
-    // Yes.  Inserts the test case after the last death test case
-    // defined so far.  This only works when the test cases haven't
+  // Is this a death test suite?
+  if (internal::UnitTestOptions::MatchesFilter(test_suite_name,
+                                               kDeathTestSuiteFilter)) {
+    // Yes.  Inserts the test suite after the last death test suite
+    // defined so far.  This only works when the test suites haven't
     // been shuffled.  Otherwise we may end up running a death test
     // after a non-death test.
-    ++last_death_test_case_;
-    test_cases_.insert(test_cases_.begin() + last_death_test_case_,
-                       new_test_case);
+    ++last_death_test_suite_;
+    test_suites_.insert(test_suites_.begin() + last_death_test_suite_,
+                        new_test_suite);
   } else {
     // No.  Appends to the end of the list.
-    test_cases_.push_back(new_test_case);
+    test_suites_.push_back(new_test_suite);
   }
 
-  test_case_indices_.push_back(static_cast<int>(test_case_indices_.size()));
-  return new_test_case;
+  test_suite_indices_.push_back(static_cast<int>(test_suite_indices_.size()));
+  return new_test_suite;
 }
 
 // Helpers for setting up / tearing down the given environment.  They
@@ -5997,13 +6623,8 @@
 // All other functions called from RunAllTests() may safely assume that
 // parameterized tests are ready to be counted and run.
 bool UnitTestImpl::RunAllTests() {
-  // Makes sure InitGoogleTest() was called.
-  if (!GTestIsInitialized()) {
-    printf("%s",
-           "\nThis test program did NOT call ::testing::InitGoogleTest "
-           "before calling RUN_ALL_TESTS().  Please fix it.\n");
-    return false;
-  }
+  // True iff Google Test is initialized before RUN_ALL_TESTS() is called.
+  const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized();
 
   // Do not run any test if the --help flag was specified.
   if (g_help_flag)
@@ -6023,7 +6644,8 @@
   bool in_subprocess_for_death_test = false;
 
 #if GTEST_HAS_DEATH_TEST
-  in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
+  in_subprocess_for_death_test =
+      (internal_run_death_test_flag_.get() != nullptr);
 # if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)
   if (in_subprocess_for_death_test) {
     GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_();
@@ -6070,7 +6692,7 @@
 
     const TimeInMillis start = GetTimeInMillis();
 
-    // Shuffles test cases and tests if requested.
+    // Shuffles test suites and tests if requested.
     if (has_tests_to_run && GTEST_FLAG(shuffle)) {
       random()->Reseed(random_seed_);
       // This should be done before calling OnTestIterationStart(),
@@ -6082,7 +6704,7 @@
     // Tells the unit test event listeners that the tests are about to start.
     repeater->OnTestIterationStart(*parent_, i);
 
-    // Runs each test case if there is at least one test to run.
+    // Runs each test suite if there is at least one test to run.
     if (has_tests_to_run) {
       // Sets up all environments beforehand.
       repeater->OnEnvironmentsSetUpStart(*parent_);
@@ -6092,9 +6714,9 @@
       // Runs the tests only if there was no fatal failure during global
       // set-up.
       if (!Test::HasFatalFailure()) {
-        for (int test_index = 0; test_index < total_test_case_count();
+        for (int test_index = 0; test_index < total_test_suite_count();
              test_index++) {
-          GetMutableTestCase(test_index)->Run();
+          GetMutableSuiteCase(test_index)->Run();
         }
       }
 
@@ -6131,6 +6753,20 @@
 
   repeater->OnTestProgramEnd(*parent_);
 
+  if (!gtest_is_initialized_before_run_all_tests) {
+    ColoredPrintf(
+        COLOR_RED,
+        "\nIMPORTANT NOTICE - DO NOT IGNORE:\n"
+        "This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_
+        "() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_
+        " will start to enforce the valid usage. "
+        "Please fix it ASAP, or IT WILL START TO FAIL.\n");  // NOLINT
+#if GTEST_FOR_GOOGLE_
+    ColoredPrintf(COLOR_RED,
+                  "For more details, see http://wiki/Main/ValidGUnitMain.\n");
+#endif  // GTEST_FOR_GOOGLE_
+  }
+
   return !failed;
 }
 
@@ -6140,9 +6776,9 @@
 // be created, prints an error and exits.
 void WriteToShardStatusFileIfNeeded() {
   const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);
-  if (test_shard_file != NULL) {
+  if (test_shard_file != nullptr) {
     FILE* const file = posix::FOpen(test_shard_file, "w");
-    if (file == NULL) {
+    if (file == nullptr) {
       ColoredPrintf(COLOR_RED,
                     "Could not write to the test shard status file \"%s\" "
                     "specified by the %s environment variable.\n",
@@ -6177,7 +6813,7 @@
       << "Invalid environment variables: you have "
       << kTestShardIndex << " = " << shard_index
       << ", but have left " << kTestTotalShards << " unset.\n";
-    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str());
     fflush(stdout);
     exit(EXIT_FAILURE);
   } else if (total_shards != -1 && shard_index == -1) {
@@ -6185,7 +6821,7 @@
       << "Invalid environment variables: you have "
       << kTestTotalShards << " = " << total_shards
       << ", but have left " << kTestShardIndex << " unset.\n";
-    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str());
     fflush(stdout);
     exit(EXIT_FAILURE);
   } else if (shard_index < 0 || shard_index >= total_shards) {
@@ -6194,7 +6830,7 @@
       << kTestShardIndex << " < " << kTestTotalShards
       << ", but you have " << kTestShardIndex << "=" << shard_index
       << ", " << kTestTotalShards << "=" << total_shards << ".\n";
-    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str());
     fflush(stdout);
     exit(EXIT_FAILURE);
   }
@@ -6207,7 +6843,7 @@
 // and aborts.
 Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) {
   const char* str_val = posix::GetEnv(var);
-  if (str_val == NULL) {
+  if (str_val == nullptr) {
     return default_val;
   }
 
@@ -6229,11 +6865,11 @@
 
 // Compares the name of each test with the user-specified filter to
 // decide whether the test should be run, then records the result in
-// each TestCase and TestInfo object.
+// each TestSuite and TestInfo object.
 // If shard_tests == true, further filters tests based on sharding
 // variables in the environment - see
-// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide.
-// Returns the number of tests that should run.
+// https://github.com/google/googletest/blob/master/googletest/docs/advanced.md
+// . Returns the number of tests that should run.
 int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
   const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ?
       Int32FromEnvOrDie(kTestTotalShards, -1) : -1;
@@ -6246,42 +6882,40 @@
   // this shard.
   int num_runnable_tests = 0;
   int num_selected_tests = 0;
-  for (size_t i = 0; i < test_cases_.size(); i++) {
-    TestCase* const test_case = test_cases_[i];
-    const std::string &test_case_name = test_case->name();
-    test_case->set_should_run(false);
+  for (auto* test_suite : test_suites_) {
+    const std::string& test_suite_name = test_suite->name();
+    test_suite->set_should_run(false);
 
-    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
-      TestInfo* const test_info = test_case->test_info_list()[j];
+    for (size_t j = 0; j < test_suite->test_info_list().size(); j++) {
+      TestInfo* const test_info = test_suite->test_info_list()[j];
       const std::string test_name(test_info->name());
-      // A test is disabled if test case name or test name matches
+      // A test is disabled if test suite name or test name matches
       // kDisableTestFilter.
-      const bool is_disabled =
-          internal::UnitTestOptions::MatchesFilter(test_case_name,
-                                                   kDisableTestFilter) ||
-          internal::UnitTestOptions::MatchesFilter(test_name,
-                                                   kDisableTestFilter);
+      const bool is_disabled = internal::UnitTestOptions::MatchesFilter(
+                                   test_suite_name, kDisableTestFilter) ||
+                               internal::UnitTestOptions::MatchesFilter(
+                                   test_name, kDisableTestFilter);
       test_info->is_disabled_ = is_disabled;
 
-      const bool matches_filter =
-          internal::UnitTestOptions::FilterMatchesTest(test_case_name,
-                                                       test_name);
+      const bool matches_filter = internal::UnitTestOptions::FilterMatchesTest(
+          test_suite_name, test_name);
       test_info->matches_filter_ = matches_filter;
 
       const bool is_runnable =
           (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
           matches_filter;
 
-      const bool is_selected = is_runnable &&
-          (shard_tests == IGNORE_SHARDING_PROTOCOL ||
-           ShouldRunTestOnShard(total_shards, shard_index,
-                                num_runnable_tests));
+      const bool is_in_another_shard =
+          shard_tests != IGNORE_SHARDING_PROTOCOL &&
+          !ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests);
+      test_info->is_in_another_shard_ = is_in_another_shard;
+      const bool is_selected = is_runnable && !is_in_another_shard;
 
       num_runnable_tests += is_runnable;
       num_selected_tests += is_selected;
 
       test_info->should_run_ = is_selected;
-      test_case->set_should_run(test_case->should_run() || is_selected);
+      test_suite->set_should_run(test_suite->should_run() || is_selected);
     }
   }
   return num_selected_tests;
@@ -6292,7 +6926,7 @@
 // max_length characters, only prints the first max_length characters
 // and "...".
 static void PrintOnOneLine(const char* str, int max_length) {
-  if (str != NULL) {
+  if (str != nullptr) {
     for (int i = 0; *str != '\0'; ++str) {
       if (i >= max_length) {
         printf("...");
@@ -6314,27 +6948,25 @@
   // Print at most this many characters for each type/value parameter.
   const int kMaxParamLength = 250;
 
-  for (size_t i = 0; i < test_cases_.size(); i++) {
-    const TestCase* const test_case = test_cases_[i];
-    bool printed_test_case_name = false;
+  for (auto* test_suite : test_suites_) {
+    bool printed_test_suite_name = false;
 
-    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
-      const TestInfo* const test_info =
-          test_case->test_info_list()[j];
+    for (size_t j = 0; j < test_suite->test_info_list().size(); j++) {
+      const TestInfo* const test_info = test_suite->test_info_list()[j];
       if (test_info->matches_filter_) {
-        if (!printed_test_case_name) {
-          printed_test_case_name = true;
-          printf("%s.", test_case->name());
-          if (test_case->type_param() != NULL) {
+        if (!printed_test_suite_name) {
+          printed_test_suite_name = true;
+          printf("%s.", test_suite->name());
+          if (test_suite->type_param() != nullptr) {
             printf("  # %s = ", kTypeParamLabel);
             // We print the type parameter on a single line to make
             // the output easy to parse by a program.
-            PrintOnOneLine(test_case->type_param(), kMaxParamLength);
+            PrintOnOneLine(test_suite->type_param(), kMaxParamLength);
           }
           printf("\n");
         }
         printf("  %s", test_info->name());
-        if (test_info->value_param() != NULL) {
+        if (test_info->value_param() != nullptr) {
           printf("  # %s = ", kValueParamLabel);
           // We print the value parameter on a single line to make the
           // output easy to parse by a program.
@@ -6345,6 +6977,23 @@
     }
   }
   fflush(stdout);
+  const std::string& output_format = UnitTestOptions::GetOutputFormat();
+  if (output_format == "xml" || output_format == "json") {
+    FILE* fileout = OpenFileForWriting(
+        UnitTestOptions::GetAbsolutePathToOutputFile().c_str());
+    std::stringstream stream;
+    if (output_format == "xml") {
+      XmlUnitTestResultPrinter(
+          UnitTestOptions::GetAbsolutePathToOutputFile().c_str())
+          .PrintXmlTestsList(&stream, test_suites_);
+    } else if (output_format == "json") {
+      JsonUnitTestResultPrinter(
+          UnitTestOptions::GetAbsolutePathToOutputFile().c_str())
+          .PrintJsonTestList(&stream, test_suites_);
+    }
+    fprintf(fileout, "%s", StringStreamToString(&stream).c_str());
+    fclose(fileout);
+  }
 }
 
 // Sets the OS stack trace getter.
@@ -6364,7 +7013,7 @@
 // otherwise, creates an OsStackTraceGetter, makes it the current
 // getter, and returns it.
 OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
-  if (os_stack_trace_getter_ == NULL) {
+  if (os_stack_trace_getter_ == nullptr) {
 #ifdef GTEST_OS_STACK_TRACE_GETTER_
     os_stack_trace_getter_ = new GTEST_OS_STACK_TRACE_GETTER_;
 #else
@@ -6375,36 +7024,40 @@
   return os_stack_trace_getter_;
 }
 
-// Returns the TestResult for the test that's currently running, or
-// the TestResult for the ad hoc test if no test is running.
+// Returns the most specific TestResult currently running.
 TestResult* UnitTestImpl::current_test_result() {
-  return current_test_info_ ?
-      &(current_test_info_->result_) : &ad_hoc_test_result_;
+  if (current_test_info_ != nullptr) {
+    return &current_test_info_->result_;
+  }
+  if (current_test_suite_ != nullptr) {
+    return &current_test_suite_->ad_hoc_test_result_;
+  }
+  return &ad_hoc_test_result_;
 }
 
-// Shuffles all test cases, and the tests within each test case,
+// Shuffles all test suites, and the tests within each test suite,
 // making sure that death tests are still run first.
 void UnitTestImpl::ShuffleTests() {
-  // Shuffles the death test cases.
-  ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_);
+  // Shuffles the death test suites.
+  ShuffleRange(random(), 0, last_death_test_suite_ + 1, &test_suite_indices_);
 
-  // Shuffles the non-death test cases.
-  ShuffleRange(random(), last_death_test_case_ + 1,
-               static_cast<int>(test_cases_.size()), &test_case_indices_);
+  // Shuffles the non-death test suites.
+  ShuffleRange(random(), last_death_test_suite_ + 1,
+               static_cast<int>(test_suites_.size()), &test_suite_indices_);
 
-  // Shuffles the tests inside each test case.
-  for (size_t i = 0; i < test_cases_.size(); i++) {
-    test_cases_[i]->ShuffleTests(random());
+  // Shuffles the tests inside each test suite.
+  for (auto& test_suite : test_suites_) {
+    test_suite->ShuffleTests(random());
   }
 }
 
-// Restores the test cases and tests to their order before the first shuffle.
+// Restores the test suites and tests to their order before the first shuffle.
 void UnitTestImpl::UnshuffleTests() {
-  for (size_t i = 0; i < test_cases_.size(); i++) {
-    // Unshuffles the tests in each test case.
-    test_cases_[i]->UnshuffleTests();
-    // Resets the index of each test case.
-    test_case_indices_[i] = static_cast<int>(i);
+  for (size_t i = 0; i < test_suites_.size(); i++) {
+    // Unshuffles the tests in each test suite.
+    test_suites_[i]->UnshuffleTests();
+    // Resets the index of each test suite.
+    test_suite_indices_[i] = static_cast<int>(i);
   }
 }
 
@@ -6460,16 +7113,15 @@
 // part can be omitted.
 //
 // Returns the value of the flag, or NULL if the parsing failed.
-const char* ParseFlagValue(const char* str,
-                           const char* flag,
-                           bool def_optional) {
+static const char* ParseFlagValue(const char* str, const char* flag,
+                                  bool def_optional) {
   // str and flag must not be NULL.
-  if (str == NULL || flag == NULL) return NULL;
+  if (str == nullptr || flag == nullptr) return nullptr;
 
   // The flag must start with "--" followed by GTEST_FLAG_PREFIX_.
   const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag;
   const size_t flag_len = flag_str.length();
-  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
+  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
 
   // Skips the flag name.
   const char* flag_end = str + flag_len;
@@ -6482,7 +7134,7 @@
   // If def_optional is true and there are more characters after the
   // flag name, or if def_optional is false, there must be a '=' after
   // the flag name.
-  if (flag_end[0] != '=') return NULL;
+  if (flag_end[0] != '=') return nullptr;
 
   // Returns the string after "=".
   return flag_end + 1;
@@ -6498,12 +7150,12 @@
 //
 // On success, stores the value of the flag in *value, and returns
 // true.  On failure, returns false without changing *value.
-bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
+static bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
   // Gets the value of the flag as a string.
   const char* const value_str = ParseFlagValue(str, flag, true);
 
   // Aborts if the parsing failed.
-  if (value_str == NULL) return false;
+  if (value_str == nullptr) return false;
 
   // Converts the string value to a bool.
   *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
@@ -6520,7 +7172,7 @@
   const char* const value_str = ParseFlagValue(str, flag, false);
 
   // Aborts if the parsing failed.
-  if (value_str == NULL) return false;
+  if (value_str == nullptr) return false;
 
   // Sets *value to the value of the flag.
   return ParseInt32(Message() << "The value of flag --" << flag,
@@ -6532,12 +7184,13 @@
 //
 // On success, stores the value of the flag in *value, and returns
 // true.  On failure, returns false without changing *value.
-bool ParseStringFlag(const char* str, const char* flag, std::string* value) {
+template <typename String>
+static bool ParseStringFlag(const char* str, const char* flag, String* value) {
   // Gets the value of the flag as a string.
   const char* const value_str = ParseFlagValue(str, flag, false);
 
   // Aborts if the parsing failed.
-  if (value_str == NULL) return false;
+  if (value_str == nullptr) return false;
 
   // Sets *value to the value of the flag.
   *value = value_str;
@@ -6568,8 +7221,6 @@
 //   @Y    changes the color to yellow.
 //   @D    changes to the default terminal text color.
 //
-// TODO(wan@google.com): Write tests for this once we add stdout
-// capturing to Google Test.
 static void PrintColorEncoded(const char* str) {
   GTestColor color = COLOR_DEFAULT;  // The current color.
 
@@ -6579,7 +7230,7 @@
   // next segment.
   for (;;) {
     const char* p = strchr(str, '@');
-    if (p == NULL) {
+    if (p == nullptr) {
       ColoredPrintf(color, "%s", str);
       return;
     }
@@ -6634,24 +7285,25 @@
 "      Enable/disable colored output. The default is @Gauto@D.\n"
 "  -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
 "      Don't print the elapsed time of each test.\n"
-"  @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G"
+"  @G--" GTEST_FLAG_PREFIX_ "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G"
     GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
-"      Generate an XML report in the given directory or with the given file\n"
-"      name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n"
-#if GTEST_CAN_STREAM_RESULTS_
+"      Generate a JSON or XML report in the given directory or with the given\n"
+"      file name. @YFILE_PATH@D defaults to @Gtest_detail.xml@D.\n"
+# if GTEST_CAN_STREAM_RESULTS_
 "  @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n"
 "      Stream test results to the given server.\n"
-#endif  // GTEST_CAN_STREAM_RESULTS_
+# endif  // GTEST_CAN_STREAM_RESULTS_
 "\n"
 "Assertion Behavior:\n"
-#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+# if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
 "  @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
 "      Set the default death test style.\n"
-#endif  // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+# endif  // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
 "  @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n"
 "      Turn assertion failures into debugger break-points.\n"
 "  @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n"
-"      Turn assertion failures into C++ exceptions.\n"
+"      Turn assertion failures into C++ exceptions for use by an external\n"
+"      test framework.\n"
 "  @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n"
 "      Do not report exceptions as test failures. Instead, allow them\n"
 "      to crash the program or throw a pop-up (on Windows).\n"
@@ -6668,7 +7320,7 @@
 "(not one in your own code or tests), please report it to\n"
 "@G<" GTEST_DEV_EMAIL_ ">@D.\n";
 
-bool ParseGoogleTestFlag(const char* const arg) {
+static bool ParseGoogleTestFlag(const char* const arg) {
   return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
                        &GTEST_FLAG(also_run_disabled_tests)) ||
       ParseBoolFlag(arg, kBreakOnFailureFlag,
@@ -6686,6 +7338,7 @@
       ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) ||
       ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) ||
       ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) ||
+      ParseBoolFlag(arg, kPrintUTF8Flag, &GTEST_FLAG(print_utf8)) ||
       ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) ||
       ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||
       ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||
@@ -6698,14 +7351,11 @@
 }
 
 #if GTEST_USE_OWN_FLAGFILE_FLAG_
-void LoadFlagsFromFile(const std::string& path) {
+static void LoadFlagsFromFile(const std::string& path) {
   FILE* flagfile = posix::FOpen(path.c_str(), "r");
   if (!flagfile) {
-    fprintf(stderr,
-            "Unable to open file \"%s\"\n",
-            GTEST_FLAG(flagfile).c_str());
-    fflush(stderr);
-    exit(EXIT_FAILURE);
+    GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG(flagfile)
+                      << "\"";
   }
   std::string contents(ReadEntireFile(flagfile));
   posix::FClose(flagfile);
@@ -6779,6 +7429,17 @@
 // other parts of Google Test.
 void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
   ParseGoogleTestFlagsOnlyImpl(argc, argv);
+
+  // Fix the value of *_NSGetArgc() on macOS, but iff
+  // *_NSGetArgv() == argv
+  // Only applicable to char** version of argv
+#if GTEST_OS_MAC
+#ifndef GTEST_OS_IOS
+  if (*_NSGetArgv() == argv) {
+    *_NSGetArgc() = *argc;
+  }
+#endif
+#endif
 }
 void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
   ParseGoogleTestFlagsOnlyImpl(argc, argv);
@@ -6800,6 +7461,10 @@
     g_argvs.push_back(StreamableToString(argv[i]));
   }
 
+#if GTEST_HAS_ABSL
+  absl::InitializeSymbolizer(g_argvs[0].c_str());
+#endif  // GTEST_HAS_ABSL
+
   ParseGoogleTestFlagsOnly(argc, argv);
   GetUnitTestImpl()->PostFlagParsingInit();
 }
@@ -6833,6 +7498,63 @@
 #endif  // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
 }
 
+// This overloaded version can be used on Arduino/embedded platforms where
+// there is no argc/argv.
+void InitGoogleTest() {
+  // Since Arduino doesn't have a command line, fake out the argc/argv arguments
+  int argc = 1;
+  const auto arg0 = "dummy";
+  char* argv0 = const_cast<char*>(arg0);
+  char** argv = &argv0;
+
+#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
+  GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(&argc, argv);
+#else  // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
+  internal::InitGoogleTestImpl(&argc, argv);
+#endif  // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
+}
+
+std::string TempDir() {
+#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
+  return GTEST_CUSTOM_TEMPDIR_FUNCTION_();
+#endif
+
+#if GTEST_OS_WINDOWS_MOBILE
+  return "\\temp\\";
+#elif GTEST_OS_WINDOWS
+  const char* temp_dir = internal::posix::GetEnv("TEMP");
+  if (temp_dir == nullptr || temp_dir[0] == '\0')
+    return "\\temp\\";
+  else if (temp_dir[strlen(temp_dir) - 1] == '\\')
+    return temp_dir;
+  else
+    return std::string(temp_dir) + "\\";
+#elif GTEST_OS_LINUX_ANDROID
+  return "/sdcard/";
+#else
+  return "/tmp/";
+#endif  // GTEST_OS_WINDOWS_MOBILE
+}
+
+// Class ScopedTrace
+
+// Pushes the given source file location and message onto a per-thread
+// trace stack maintained by Google Test.
+void ScopedTrace::PushTrace(const char* file, int line, std::string message) {
+  internal::TraceInfo trace;
+  trace.file = file;
+  trace.line = line;
+  trace.message.swap(message);
+
+  UnitTest::GetInstance()->PushGTestTrace(trace);
+}
+
+// Pops the info pushed by the c'tor.
+ScopedTrace::~ScopedTrace()
+    GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
+  UnitTest::GetInstance()->PopGTestTrace();
+}
+
 }  // namespace testing
 // Copyright 2005, Google Inc.
 // All rights reserved.
@@ -6862,12 +7584,14 @@
 // 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: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev)
+
 //
 // This file implements death tests.
 
 
+#include <utility>
+
+
 #if GTEST_HAS_DEATH_TEST
 
 # if GTEST_OS_MAC
@@ -6895,23 +7619,32 @@
 #  include <spawn.h>
 # endif  // GTEST_OS_QNX
 
+# if GTEST_OS_FUCHSIA
+#  include <lib/fdio/fd.h>
+#  include <lib/fdio/io.h>
+#  include <lib/fdio/spawn.h>
+#  include <lib/zx/port.h>
+#  include <lib/zx/process.h>
+#  include <lib/zx/socket.h>
+#  include <zircon/processargs.h>
+#  include <zircon/syscalls.h>
+#  include <zircon/syscalls/policy.h>
+#  include <zircon/syscalls/port.h>
+# endif  // GTEST_OS_FUCHSIA
+
 #endif  // GTEST_HAS_DEATH_TEST
 
 
-// Indicates that this translation unit is part of Google Test's
-// implementation.  It must come before gtest-internal-inl.h is
-// included, or there will be a compiler error.  This trick exists to
-// prevent the accidental inclusion of gtest-internal-inl.h in the
-// user's code.
-#define GTEST_IMPLEMENTATION_ 1
-#undef GTEST_IMPLEMENTATION_
-
 namespace testing {
 
 // Constants.
 
 // The default death test style.
-static const char kDefaultDeathTestStyle[] = "fast";
+//
+// This is defined in internal/gtest-port.h as "fast", but can be overridden by
+// a definition in internal/custom/gtest-port.h. The recommended value, which is
+// used internally at Google, is "threadsafe".
+static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE;
 
 GTEST_DEFINE_string_(
     death_test_style,
@@ -6951,7 +7684,7 @@
 
 // Valid only for fast death tests. Indicates the code is running in the
 // child process of a fast style death test.
-# if !GTEST_OS_WINDOWS
+# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
 static bool g_in_fast_death_test_child = false;
 # endif
 
@@ -6961,10 +7694,10 @@
 // tests.  IMPORTANT: This is an internal utility.  Using it may break the
 // implementation of death tests.  User code MUST NOT use it.
 bool InDeathTestChild() {
-# if GTEST_OS_WINDOWS
+# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
 
-  // On Windows, death tests are thread-safe regardless of the value of the
-  // death_test_style flag.
+  // On Windows and Fuchsia, death tests are thread-safe regardless of the value
+  // of the death_test_style flag.
   return !GTEST_FLAG(internal_run_death_test).empty();
 
 # else
@@ -6984,7 +7717,7 @@
 
 // ExitedWithCode function-call operator.
 bool ExitedWithCode::operator()(int exit_status) const {
-# if GTEST_OS_WINDOWS
+# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
 
   return exit_status == exit_code_;
 
@@ -6992,10 +7725,10 @@
 
   return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;
 
-# endif  // GTEST_OS_WINDOWS
+# endif  // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
 }
 
-# if !GTEST_OS_WINDOWS
+# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
 // KilledBySignal constructor.
 KilledBySignal::KilledBySignal(int signum) : signum_(signum) {
 }
@@ -7012,7 +7745,7 @@
 #  endif  // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_)
   return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;
 }
-# endif  // !GTEST_OS_WINDOWS
+# endif  // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
 
 namespace internal {
 
@@ -7023,7 +7756,7 @@
 static std::string ExitSummary(int exit_code) {
   Message m;
 
-# if GTEST_OS_WINDOWS
+# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
 
   m << "Exited with exit status " << exit_code;
 
@@ -7039,7 +7772,7 @@
     m << " (core dumped)";
   }
 #  endif
-# endif  // GTEST_OS_WINDOWS
+# endif  // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
 
   return m.GetString();
 }
@@ -7050,7 +7783,7 @@
   return !ExitedWithCode(0)(exit_status);
 }
 
-# if !GTEST_OS_WINDOWS
+# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
 // Generates a textual failure message when a death test finds more than
 // one thread running, or cannot determine the number of threads, prior
 // to executing the given statement.  It is the responsibility of the
@@ -7059,13 +7792,19 @@
   Message msg;
   msg << "Death tests use fork(), which is unsafe particularly"
       << " in a threaded context. For this test, " << GTEST_NAME_ << " ";
-  if (thread_count == 0)
+  if (thread_count == 0) {
     msg << "couldn't detect the number of threads.";
-  else
+  } else {
     msg << "detected " << thread_count << " threads.";
+  }
+  msg << " See "
+         "https://github.com/google/googletest/blob/master/googletest/docs/"
+         "advanced.md#death-tests-and-threads"
+      << " for more explanation and suggested solutions, especially if"
+      << " this is the last message you see before your test times out.";
   return msg.GetString();
 }
-# endif  // !GTEST_OS_WINDOWS
+# endif  // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
 
 // Flag characters for reporting a death test that did not die.
 static const char kDeathTestLived = 'L';
@@ -7073,6 +7812,13 @@
 static const char kDeathTestThrew = 'T';
 static const char kDeathTestInternalError = 'I';
 
+#if GTEST_OS_FUCHSIA
+
+// File descriptor used for the pipe in the child process.
+static const int kFuchsiaReadPipeFd = 3;
+
+#endif
+
 // An enumeration describing all of the possible ways that a death test can
 // conclude.  DIED means that the process died while executing the test
 // code; LIVED means that process lived beyond the end of the test code;
@@ -7080,8 +7826,6 @@
 // statement, which is not allowed; THREW means that the test statement
 // returned control by throwing an exception.  IN_PROGRESS means the test
 // has not yet concluded.
-// TODO(vladl@google.com): Unify names and possibly values for
-// AbortReason, DeathTestOutcome, and flag characters above.
 enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
 
 // Routine for aborting the program which is safe to call from an
@@ -7089,13 +7833,13 @@
 // message is propagated back to the parent process.  Otherwise, the
 // message is simply printed to stderr.  In either case, the program
 // then exits with status 1.
-void DeathTestAbort(const std::string& message) {
+static void DeathTestAbort(const std::string& message) {
   // On a POSIX system, this function may be called from a threadsafe-style
   // death test child process, which operates on a very small stack.  Use
   // the heap for any additional non-minuscule memory requirements.
   const InternalRunDeathTestFlag* const flag =
       GetUnitTestImpl()->internal_run_death_test_flag();
-  if (flag != NULL) {
+  if (flag != nullptr) {
     FILE* parent = posix::FDOpen(flag->write_fd(), "w");
     fputc(kDeathTestInternalError, parent);
     fprintf(parent, "%s", message.c_str());
@@ -7175,7 +7919,7 @@
 // for the current test.
 DeathTest::DeathTest() {
   TestInfo* const info = GetUnitTestImpl()->current_test_info();
-  if (info == NULL) {
+  if (info == nullptr) {
     DeathTestAbort("Cannot run a death test outside of a TEST or "
                    "TEST_F construct");
   }
@@ -7183,10 +7927,11 @@
 
 // Creates and returns a death test by dispatching to the current
 // death test factory.
-bool DeathTest::Create(const char* statement, const RE* regex,
-                       const char* file, int line, DeathTest** test) {
+bool DeathTest::Create(const char* statement,
+                       Matcher<const std::string&> matcher, const char* file,
+                       int line, DeathTest** test) {
   return GetUnitTestImpl()->death_test_factory()->Create(
-      statement, regex, file, line, test);
+      statement, std::move(matcher), file, line, test);
 }
 
 const char* DeathTest::LastMessage() {
@@ -7202,9 +7947,9 @@
 // Provides cross platform implementation for some death functionality.
 class DeathTestImpl : public DeathTest {
  protected:
-  DeathTestImpl(const char* a_statement, const RE* a_regex)
+  DeathTestImpl(const char* a_statement, Matcher<const std::string&> matcher)
       : statement_(a_statement),
-        regex_(a_regex),
+        matcher_(std::move(matcher)),
         spawned_(false),
         status_(-1),
         outcome_(IN_PROGRESS),
@@ -7212,13 +7957,12 @@
         write_fd_(-1) {}
 
   // read_fd_ is expected to be closed and cleared by a derived class.
-  ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }
+  ~DeathTestImpl() override { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }
 
-  void Abort(AbortReason reason);
-  virtual bool Passed(bool status_ok);
+  void Abort(AbortReason reason) override;
+  bool Passed(bool status_ok) override;
 
   const char* statement() const { return statement_; }
-  const RE* regex() const { return regex_; }
   bool spawned() const { return spawned_; }
   void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
   int status() const { return status_; }
@@ -7236,13 +7980,15 @@
   // case of unexpected codes.
   void ReadAndInterpretStatusByte();
 
+  // Returns stderr output from the child process.
+  virtual std::string GetErrorLogs();
+
  private:
   // The textual content of the code this object is testing.  This class
   // doesn't own this string and should not attempt to delete it.
   const char* const statement_;
-  // The regular expression which test output must match.  DeathTestImpl
-  // doesn't own this object and should not attempt to delete it.
-  const RE* const regex_;
+  // A matcher that's expected to match the stderr output by the child process.
+  Matcher<const std::string&> matcher_;
   // True if the death test child process has been successfully spawned.
   bool spawned_;
   // The exit status of the child process.
@@ -7304,6 +8050,10 @@
   set_read_fd(-1);
 }
 
+std::string DeathTestImpl::GetErrorLogs() {
+  return GetCapturedStderr();
+}
+
 // Signals that the death test code which should have exited, didn't.
 // Should be called only in a death test child process.
 // Writes a status byte to the child's status file descriptor, then
@@ -7357,9 +8107,8 @@
 //             in the format specified by wait(2). On Windows, this is the
 //             value supplied to the ExitProcess() API or a numeric code
 //             of the exception that terminated the program.
-//   regex:    A regular expression object to be applied to
-//             the test's captured standard error output; the death test
-//             fails if it does not match.
+//   matcher_: A matcher that's expected to match the stderr output by the child
+//             process.
 //
 // Argument:
 //   status_ok: true if exit_status is acceptable in the context of
@@ -7372,7 +8121,7 @@
   if (!spawned())
     return false;
 
-  const std::string error_message = GetCapturedStderr();
+  const std::string error_message = GetErrorLogs();
 
   bool success = false;
   Message buffer;
@@ -7393,13 +8142,15 @@
       break;
     case DIED:
       if (status_ok) {
-        const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
-        if (matched) {
+        if (matcher_.Matches(error_message)) {
           success = true;
         } else {
+          std::ostringstream stream;
+          matcher_.DescribeTo(&stream);
           buffer << "    Result: died but not with expected error.\n"
-                 << "  Expected: " << regex()->pattern() << "\n"
-                 << "Actual msg:\n" << FormatDeathTestOutput(error_message);
+                 << "  Expected: " << stream.str() << "\n"
+                 << "Actual msg:\n"
+                 << FormatDeathTestOutput(error_message);
         }
       } else {
         buffer << "    Result: died but not with expected exit code:\n"
@@ -7448,11 +8199,11 @@
 //
 class WindowsDeathTest : public DeathTestImpl {
  public:
-  WindowsDeathTest(const char* a_statement,
-                   const RE* a_regex,
-                   const char* file,
-                   int line)
-      : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {}
+  WindowsDeathTest(const char* a_statement, Matcher<const std::string&> matcher,
+                   const char* file, int line)
+      : DeathTestImpl(a_statement, std::move(matcher)),
+        file_(file),
+        line_(line) {}
 
   // All of these virtual functions are inherited from DeathTest.
   virtual int Wait();
@@ -7529,7 +8280,7 @@
   const TestInfo* const info = impl->current_test_info();
   const int death_test_index = info->result()->death_test_count();
 
-  if (flag != NULL) {
+  if (flag != nullptr) {
     // ParseInternalRunDeathTestFlag() has performed all the necessary
     // processing.
     set_write_fd(flag->write_fd());
@@ -7538,8 +8289,8 @@
 
   // WindowsDeathTest uses an anonymous pipe to communicate results of
   // a death test.
-  SECURITY_ATTRIBUTES handles_are_inheritable = {
-    sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
+  SECURITY_ATTRIBUTES handles_are_inheritable = {sizeof(SECURITY_ATTRIBUTES),
+                                                 nullptr, TRUE};
   HANDLE read_handle, write_handle;
   GTEST_DEATH_TEST_CHECK_(
       ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable,
@@ -7550,13 +8301,13 @@
   write_handle_.Reset(write_handle);
   event_handle_.Reset(::CreateEvent(
       &handles_are_inheritable,
-      TRUE,    // The event will automatically reset to non-signaled state.
-      FALSE,   // The initial state is non-signalled.
-      NULL));  // The even is unnamed.
-  GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL);
-  const std::string filter_flag =
-      std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" +
-      info->test_case_name() + "." + info->name();
+      TRUE,       // The event will automatically reset to non-signaled state.
+      FALSE,      // The initial state is non-signalled.
+      nullptr));  // The even is unnamed.
+  GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr);
+  const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
+                                  kFilterFlag + "=" + info->test_suite_name() +
+                                  "." + info->name();
   const std::string internal_flag =
       std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag +
       "=" + file_ + "|" + StreamableToString(line_) + "|" +
@@ -7569,10 +8320,9 @@
       "|" + StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
 
   char executable_path[_MAX_PATH + 1];  // NOLINT
-  GTEST_DEATH_TEST_CHECK_(
-      _MAX_PATH + 1 != ::GetModuleFileNameA(NULL,
-                                            executable_path,
-                                            _MAX_PATH));
+  GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr,
+                                                                executable_path,
+                                                                _MAX_PATH));
 
   std::string command_line =
       std::string(::GetCommandLineA()) + " " + filter_flag + " \"" +
@@ -7593,33 +8343,277 @@
   startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
 
   PROCESS_INFORMATION process_info;
-  GTEST_DEATH_TEST_CHECK_(::CreateProcessA(
-      executable_path,
-      const_cast<char*>(command_line.c_str()),
-      NULL,   // Retuned process handle is not inheritable.
-      NULL,   // Retuned thread handle is not inheritable.
-      TRUE,   // Child inherits all inheritable handles (for write_handle_).
-      0x0,    // Default creation flags.
-      NULL,   // Inherit the parent's environment.
-      UnitTest::GetInstance()->original_working_dir(),
-      &startup_info,
-      &process_info) != FALSE);
+  GTEST_DEATH_TEST_CHECK_(
+      ::CreateProcessA(
+          executable_path, const_cast<char*>(command_line.c_str()),
+          nullptr,  // Retuned process handle is not inheritable.
+          nullptr,  // Retuned thread handle is not inheritable.
+          TRUE,  // Child inherits all inheritable handles (for write_handle_).
+          0x0,   // Default creation flags.
+          nullptr,  // Inherit the parent's environment.
+          UnitTest::GetInstance()->original_working_dir(), &startup_info,
+          &process_info) != FALSE);
   child_handle_.Reset(process_info.hProcess);
   ::CloseHandle(process_info.hThread);
   set_spawned(true);
   return OVERSEE_TEST;
 }
-# else  // We are not on Windows.
+
+# elif GTEST_OS_FUCHSIA
+
+class FuchsiaDeathTest : public DeathTestImpl {
+ public:
+  FuchsiaDeathTest(const char* a_statement, Matcher<const std::string&> matcher,
+                   const char* file, int line)
+      : DeathTestImpl(a_statement, std::move(matcher)),
+        file_(file),
+        line_(line) {}
+
+  // All of these virtual functions are inherited from DeathTest.
+  int Wait() override;
+  TestRole AssumeRole() override;
+  std::string GetErrorLogs() override;
+
+ private:
+  // The name of the file in which the death test is located.
+  const char* const file_;
+  // The line number on which the death test is located.
+  const int line_;
+  // The stderr data captured by the child process.
+  std::string captured_stderr_;
+
+  zx::process child_process_;
+  zx::port port_;
+  zx::socket stderr_socket_;
+};
+
+// Utility class for accumulating command-line arguments.
+class Arguments {
+ public:
+  Arguments() { args_.push_back(nullptr); }
+
+  ~Arguments() {
+    for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
+         ++i) {
+      free(*i);
+    }
+  }
+  void AddArgument(const char* argument) {
+    args_.insert(args_.end() - 1, posix::StrDup(argument));
+  }
+
+  template <typename Str>
+  void AddArguments(const ::std::vector<Str>& arguments) {
+    for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
+         i != arguments.end();
+         ++i) {
+      args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
+    }
+  }
+  char* const* Argv() {
+    return &args_[0];
+  }
+
+  int size() {
+    return args_.size() - 1;
+  }
+
+ private:
+  std::vector<char*> args_;
+};
+
+// Waits for the child in a death test to exit, returning its exit
+// status, or 0 if no child process exists.  As a side effect, sets the
+// outcome data member.
+int FuchsiaDeathTest::Wait() {
+  const int kProcessKey = 0;
+  const int kSocketKey = 1;
+
+  if (!spawned())
+    return 0;
+
+  // Register to wait for the child process to terminate.
+  zx_status_t status_zx;
+  status_zx = child_process_.wait_async(
+      port_, kProcessKey, ZX_PROCESS_TERMINATED, ZX_WAIT_ASYNC_ONCE);
+  GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+  // Register to wait for the socket to be readable or closed.
+  status_zx = stderr_socket_.wait_async(
+      port_, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED,
+      ZX_WAIT_ASYNC_REPEATING);
+  GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+
+  bool process_terminated = false;
+  bool socket_closed = false;
+  do {
+    zx_port_packet_t packet = {};
+    status_zx = port_.wait(zx::time::infinite(), &packet);
+    GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+
+    if (packet.key == kProcessKey) {
+      if (ZX_PKT_IS_EXCEPTION(packet.type)) {
+        // Process encountered an exception. Kill it directly rather than
+        // letting other handlers process the event. We will get a second
+        // kProcessKey event when the process actually terminates.
+        status_zx = child_process_.kill();
+        GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+      } else {
+        // Process terminated.
+        GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type));
+        GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_PROCESS_TERMINATED);
+        process_terminated = true;
+      }
+    } else if (packet.key == kSocketKey) {
+      GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_REP(packet.type));
+      if (packet.signal.observed & ZX_SOCKET_READABLE) {
+        // Read data from the socket.
+        constexpr size_t kBufferSize = 1024;
+        do {
+          size_t old_length = captured_stderr_.length();
+          size_t bytes_read = 0;
+          captured_stderr_.resize(old_length + kBufferSize);
+          status_zx = stderr_socket_.read(
+              0, &captured_stderr_.front() + old_length, kBufferSize,
+              &bytes_read);
+          captured_stderr_.resize(old_length + bytes_read);
+        } while (status_zx == ZX_OK);
+        if (status_zx == ZX_ERR_PEER_CLOSED) {
+          socket_closed = true;
+        } else {
+          GTEST_DEATH_TEST_CHECK_(status_zx == ZX_ERR_SHOULD_WAIT);
+        }
+      } else {
+        GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_SOCKET_PEER_CLOSED);
+        socket_closed = true;
+      }
+    }
+  } while (!process_terminated && !socket_closed);
+
+  ReadAndInterpretStatusByte();
+
+  zx_info_process_t buffer;
+  status_zx = child_process_.get_info(
+      ZX_INFO_PROCESS, &buffer, sizeof(buffer), nullptr, nullptr);
+  GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+
+  GTEST_DEATH_TEST_CHECK_(buffer.exited);
+  set_status(buffer.return_code);
+  return status();
+}
+
+// The AssumeRole process for a Fuchsia death test.  It creates a child
+// process with the same executable as the current process to run the
+// death test.  The child process is given the --gtest_filter and
+// --gtest_internal_run_death_test flags such that it knows to run the
+// current death test only.
+DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
+  const UnitTestImpl* const impl = GetUnitTestImpl();
+  const InternalRunDeathTestFlag* const flag =
+      impl->internal_run_death_test_flag();
+  const TestInfo* const info = impl->current_test_info();
+  const int death_test_index = info->result()->death_test_count();
+
+  if (flag != nullptr) {
+    // ParseInternalRunDeathTestFlag() has performed all the necessary
+    // processing.
+    set_write_fd(kFuchsiaReadPipeFd);
+    return EXECUTE_TEST;
+  }
+
+  // Flush the log buffers since the log streams are shared with the child.
+  FlushInfoLog();
+
+  // Build the child process command line.
+  const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
+                                  kFilterFlag + "=" + info->test_suite_name() +
+                                  "." + info->name();
+  const std::string internal_flag =
+      std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "="
+      + file_ + "|"
+      + StreamableToString(line_) + "|"
+      + StreamableToString(death_test_index);
+  Arguments args;
+  args.AddArguments(GetInjectableArgvs());
+  args.AddArgument(filter_flag.c_str());
+  args.AddArgument(internal_flag.c_str());
+
+  // Build the pipe for communication with the child.
+  zx_status_t status;
+  zx_handle_t child_pipe_handle;
+  uint32_t type;
+  status = fdio_pipe_half(&child_pipe_handle, &type);
+  GTEST_DEATH_TEST_CHECK_(status >= 0);
+  set_read_fd(status);
+
+  // Set the pipe handle for the child.
+  fdio_spawn_action_t spawn_actions[2] = {};
+  fdio_spawn_action_t* add_handle_action = &spawn_actions[0];
+  add_handle_action->action = FDIO_SPAWN_ACTION_ADD_HANDLE;
+  add_handle_action->h.id = PA_HND(type, kFuchsiaReadPipeFd);
+  add_handle_action->h.handle = child_pipe_handle;
+
+  // Create a socket pair will be used to receive the child process' stderr.
+  zx::socket stderr_producer_socket;
+  status =
+      zx::socket::create(0, &stderr_producer_socket, &stderr_socket_);
+  GTEST_DEATH_TEST_CHECK_(status >= 0);
+  int stderr_producer_fd = -1;
+  status =
+      fdio_fd_create(stderr_producer_socket.release(), &stderr_producer_fd);
+  GTEST_DEATH_TEST_CHECK_(status >= 0);
+
+  // Make the stderr socket nonblocking.
+  GTEST_DEATH_TEST_CHECK_(fcntl(stderr_producer_fd, F_SETFL, 0) == 0);
+
+  fdio_spawn_action_t* add_stderr_action = &spawn_actions[1];
+  add_stderr_action->action = FDIO_SPAWN_ACTION_CLONE_FD;
+  add_stderr_action->fd.local_fd = stderr_producer_fd;
+  add_stderr_action->fd.target_fd = STDERR_FILENO;
+
+  // Create a child job.
+  zx_handle_t child_job = ZX_HANDLE_INVALID;
+  status = zx_job_create(zx_job_default(), 0, & child_job);
+  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
+  zx_policy_basic_t policy;
+  policy.condition = ZX_POL_NEW_ANY;
+  policy.policy = ZX_POL_ACTION_ALLOW;
+  status = zx_job_set_policy(
+      child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC, &policy, 1);
+  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
+
+  // Create an exception port and attach it to the |child_job|, to allow
+  // us to suppress the system default exception handler from firing.
+  status = zx::port::create(0, &port_);
+  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
+  status = zx_task_bind_exception_port(
+      child_job, port_.get(), 0 /* key */, 0 /*options */);
+  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
+
+  // Spawn the child process.
+  status = fdio_spawn_etc(
+      child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0], args.Argv(), nullptr,
+      2, spawn_actions, child_process_.reset_and_get_address(), nullptr);
+  GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
+
+  set_spawned(true);
+  return OVERSEE_TEST;
+}
+
+std::string FuchsiaDeathTest::GetErrorLogs() {
+  return captured_stderr_;
+}
+
+#else  // We are neither on Windows, nor on Fuchsia.
 
 // ForkingDeathTest provides implementations for most of the abstract
 // methods of the DeathTest interface.  Only the AssumeRole method is
 // left undefined.
 class ForkingDeathTest : public DeathTestImpl {
  public:
-  ForkingDeathTest(const char* statement, const RE* regex);
+  ForkingDeathTest(const char* statement, Matcher<const std::string&> matcher);
 
   // All of these virtual functions are inherited from DeathTest.
-  virtual int Wait();
+  int Wait() override;
 
  protected:
   void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
@@ -7630,9 +8624,9 @@
 };
 
 // Constructs a ForkingDeathTest.
-ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex)
-    : DeathTestImpl(a_statement, a_regex),
-      child_pid_(-1) {}
+ForkingDeathTest::ForkingDeathTest(const char* a_statement,
+                                   Matcher<const std::string&> matcher)
+    : DeathTestImpl(a_statement, std::move(matcher)), child_pid_(-1) {}
 
 // Waits for the child in a death test to exit, returning its exit
 // status, or 0 if no child process exists.  As a side effect, sets the
@@ -7653,9 +8647,9 @@
 // in the child process.
 class NoExecDeathTest : public ForkingDeathTest {
  public:
-  NoExecDeathTest(const char* a_statement, const RE* a_regex) :
-      ForkingDeathTest(a_statement, a_regex) { }
-  virtual TestRole AssumeRole();
+  NoExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher)
+      : ForkingDeathTest(a_statement, std::move(matcher)) {}
+  TestRole AssumeRole() override;
 };
 
 // The AssumeRole process for a fork-and-run death test.  It implements a
@@ -7708,16 +8702,18 @@
 // only this specific death test to be run.
 class ExecDeathTest : public ForkingDeathTest {
  public:
-  ExecDeathTest(const char* a_statement, const RE* a_regex,
-                const char* file, int line) :
-      ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { }
-  virtual TestRole AssumeRole();
+  ExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher,
+                const char* file, int line)
+      : ForkingDeathTest(a_statement, std::move(matcher)),
+        file_(file),
+        line_(line) {}
+  TestRole AssumeRole() override;
+
  private:
-  static ::std::vector<testing::internal::string>
-  GetArgvsForDeathTestChildProcess() {
-    ::std::vector<testing::internal::string> args = GetInjectableArgvs();
+  static ::std::vector<std::string> GetArgvsForDeathTestChildProcess() {
+    ::std::vector<std::string> args = GetInjectableArgvs();
 #  if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)
-    ::std::vector<testing::internal::string> extra_args =
+    ::std::vector<std::string> extra_args =
         GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_();
     args.insert(args.end(), extra_args.begin(), extra_args.end());
 #  endif  // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)
@@ -7732,9 +8728,7 @@
 // Utility class for accumulating command-line arguments.
 class Arguments {
  public:
-  Arguments() {
-    args_.push_back(NULL);
-  }
+  Arguments() { args_.push_back(nullptr); }
 
   ~Arguments() {
     for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
@@ -7816,6 +8810,7 @@
 }
 #  endif  // !GTEST_OS_QNX
 
+#  if GTEST_HAS_CLONE
 // Two utility routines that together determine the direction the stack
 // grows.
 // This could be accomplished more elegantly by a single recursive
@@ -7825,20 +8820,22 @@
 // GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining
 // StackLowerThanAddress into StackGrowsDown, which then doesn't give
 // correct answer.
-void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_;
-void StackLowerThanAddress(const void* ptr, bool* result) {
+static void StackLowerThanAddress(const void* ptr,
+                                  bool* result) GTEST_NO_INLINE_;
+static void StackLowerThanAddress(const void* ptr, bool* result) {
   int dummy;
   *result = (&dummy < ptr);
 }
 
 // Make sure AddressSanitizer does not tamper with the stack here.
 GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
-bool StackGrowsDown() {
+static bool StackGrowsDown() {
   int dummy;
   bool result;
   StackLowerThanAddress(&dummy, &result);
   return result;
 }
+#  endif  // GTEST_HAS_CLONE
 
 // Spawns a child process with the same executable as the current process in
 // a thread-safe manner and instructs it to run the death test.  The
@@ -7876,7 +8873,8 @@
                                         fd_flags | FD_CLOEXEC));
   struct inheritance inherit = {0};
   // spawn is a system call.
-  child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron());
+  child_pid =
+      spawn(args.argv[0], 0, nullptr, &inherit, args.argv, GetEnviron());
   // Restores the current working directory.
   GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1);
   GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd));
@@ -7902,7 +8900,7 @@
     static const bool stack_grows_down = StackGrowsDown();
     const size_t stack_size = getpagesize();
     // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.
-    void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE,
+    void* const stack = mmap(nullptr, stack_size, PROT_READ | PROT_WRITE,
                              MAP_ANON | MAP_PRIVATE, -1, 0);
     GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);
 
@@ -7934,7 +8932,7 @@
 #  endif  // GTEST_OS_QNX
 #  if GTEST_OS_LINUX
   GTEST_DEATH_TEST_CHECK_SYSCALL_(
-      sigaction(SIGPROF, &saved_sigprof_action, NULL));
+      sigaction(SIGPROF, &saved_sigprof_action, nullptr));
 #  endif  // GTEST_OS_LINUX
 
   GTEST_DEATH_TEST_CHECK_(child_pid != -1);
@@ -7952,7 +8950,7 @@
   const TestInfo* const info = impl->current_test_info();
   const int death_test_index = info->result()->death_test_count();
 
-  if (flag != NULL) {
+  if (flag != nullptr) {
     set_write_fd(flag->write_fd());
     return EXECUTE_TEST;
   }
@@ -7963,9 +8961,9 @@
   // it be closed when the child process does an exec:
   GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
 
-  const std::string filter_flag =
-      std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "="
-      + info->test_case_name() + "." + info->name();
+  const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
+                                  kFilterFlag + "=" + info->test_suite_name() +
+                                  "." + info->name();
   const std::string internal_flag =
       std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "="
       + file_ + "|" + StreamableToString(line_) + "|"
@@ -7998,7 +8996,8 @@
 // by the "test" argument to its address.  If the test should be
 // skipped, sets that pointer to NULL.  Returns true, unless the
 // flag is set to an invalid value.
-bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
+bool DefaultDeathTestFactory::Create(const char* statement,
+                                     Matcher<const std::string&> matcher,
                                      const char* file, int line,
                                      DeathTest** test) {
   UnitTestImpl* const impl = GetUnitTestImpl();
@@ -8007,7 +9006,7 @@
   const int death_test_index = impl->current_test_info()
       ->increment_death_test_count();
 
-  if (flag != NULL) {
+  if (flag != nullptr) {
     if (death_test_index > flag->index()) {
       DeathTest::set_last_death_test_message(
           "Death test count (" + StreamableToString(death_test_index)
@@ -8018,7 +9017,7 @@
 
     if (!(flag->file() == file && flag->line() == line &&
           flag->index() == death_test_index)) {
-      *test = NULL;
+      *test = nullptr;
       return true;
     }
   }
@@ -8027,15 +9026,22 @@
 
   if (GTEST_FLAG(death_test_style) == "threadsafe" ||
       GTEST_FLAG(death_test_style) == "fast") {
-    *test = new WindowsDeathTest(statement, regex, file, line);
+    *test = new WindowsDeathTest(statement, std::move(matcher), file, line);
+  }
+
+# elif GTEST_OS_FUCHSIA
+
+  if (GTEST_FLAG(death_test_style) == "threadsafe" ||
+      GTEST_FLAG(death_test_style) == "fast") {
+    *test = new FuchsiaDeathTest(statement, std::move(matcher), file, line);
   }
 
 # else
 
   if (GTEST_FLAG(death_test_style) == "threadsafe") {
-    *test = new ExecDeathTest(statement, regex, file, line);
+    *test = new ExecDeathTest(statement, std::move(matcher), file, line);
   } else if (GTEST_FLAG(death_test_style) == "fast") {
-    *test = new NoExecDeathTest(statement, regex);
+    *test = new NoExecDeathTest(statement, std::move(matcher));
   }
 
 # endif  // GTEST_OS_WINDOWS
@@ -8054,7 +9060,7 @@
 // Recreates the pipe and event handles from the provided parameters,
 // signals the event, and returns a file descriptor wrapped around the pipe
 // handle. This function is called in the child process only.
-int GetStatusFileDescriptor(unsigned int parent_process_id,
+static int GetStatusFileDescriptor(unsigned int parent_process_id,
                             size_t write_handle_as_size_t,
                             size_t event_handle_as_size_t) {
   AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
@@ -8065,15 +9071,13 @@
                    StreamableToString(parent_process_id));
   }
 
-  // TODO(vladl@google.com): Replace the following check with a
-  // compile-time assertion when available.
   GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
 
   const HANDLE write_handle =
       reinterpret_cast<HANDLE>(write_handle_as_size_t);
   HANDLE dup_write_handle;
 
-  // The newly initialized handle is accessible only in in the parent
+  // The newly initialized handle is accessible only in the parent
   // process. To obtain one accessible within the child, we need to use
   // DuplicateHandle.
   if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,
@@ -8122,7 +9126,7 @@
 // initialized from the GTEST_FLAG(internal_run_death_test) flag if
 // the flag is specified; otherwise returns NULL.
 InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
-  if (GTEST_FLAG(internal_run_death_test) == "") return NULL;
+  if (GTEST_FLAG(internal_run_death_test) == "") return nullptr;
 
   // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
   // can use it here.
@@ -8150,6 +9154,16 @@
   write_fd = GetStatusFileDescriptor(parent_process_id,
                                      write_handle_as_size_t,
                                      event_handle_as_size_t);
+
+# elif GTEST_OS_FUCHSIA
+
+  if (fields.size() != 3
+      || !ParseNaturalNumber(fields[1], &line)
+      || !ParseNaturalNumber(fields[2], &index)) {
+    DeathTestAbort("Bad --gtest_internal_run_death_test flag: "
+        + GTEST_FLAG(internal_run_death_test));
+  }
+
 # else
 
   if (fields.size() != 4
@@ -8198,8 +9212,6 @@
 // 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.
-//
-// Authors: keith.ray@gmail.com (Keith Ray)
 
 
 #include <stdlib.h>
@@ -8209,14 +9221,12 @@
 #elif GTEST_OS_WINDOWS
 # include <direct.h>
 # include <io.h>
-#elif GTEST_OS_SYMBIAN
-// Symbian OpenC has PATH_MAX in sys/syslimits.h
-# include <sys/syslimits.h>
 #else
 # include <limits.h>
 # include <climits>  // Some Linux distributions define PATH_MAX here.
 #endif  // GTEST_OS_WINDOWS_MOBILE
 
+
 #if GTEST_OS_WINDOWS
 # define GTEST_PATH_MAX_ _MAX_PATH
 #elif defined(PATH_MAX)
@@ -8227,7 +9237,6 @@
 # define GTEST_PATH_MAX_ _POSIX_PATH_MAX
 #endif  // GTEST_OS_WINDOWS
 
-
 namespace testing {
 namespace internal {
 
@@ -8265,13 +9274,14 @@
 
 // Returns the current working directory, or "" if unsuccessful.
 FilePath FilePath::GetCurrentDir() {
-#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
-  // Windows CE doesn't have a current directory, so we just return
+#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
+    GTEST_OS_WINDOWS_RT || ARDUINO
+  // Windows CE and Arduino don't have a current directory, so we just return
   // something reasonable.
   return FilePath(kCurrentDirectoryString);
 #elif GTEST_OS_WINDOWS
   char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
-  return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
+  return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? "" : cwd);
 #else
   char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
   char* result = getcwd(cwd, sizeof(cwd));
@@ -8279,9 +9289,9 @@
   // getcwd will likely fail in NaCl due to the sandbox, so return something
   // reasonable. The user may have provided a shim implementation for getcwd,
   // however, so fallback only when failure is detected.
-  return FilePath(result == NULL ? kCurrentDirectoryString : cwd);
+  return FilePath(result == nullptr ? kCurrentDirectoryString : cwd);
 # endif  // GTEST_OS_NACL
-  return FilePath(result == NULL ? "" : cwd);
+  return FilePath(result == nullptr ? "" : cwd);
 #endif  // GTEST_OS_WINDOWS_MOBILE
 }
 
@@ -8298,7 +9308,7 @@
   return *this;
 }
 
-// Returns a pointer to the last occurence of a valid path separator in
+// Returns a pointer to the last occurrence of a valid path separator in
 // the FilePath. On Windows, for example, both '/' and '\' are valid path
 // separators. Returns NULL if no path separator was found.
 const char* FilePath::FindLastPathSeparator() const {
@@ -8306,8 +9316,8 @@
 #if GTEST_HAS_ALT_PATH_SEP_
   const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
   // Comparing two pointers of which only one is NULL is undefined.
-  if (last_alt_sep != NULL &&
-      (last_sep == NULL || last_alt_sep > last_sep)) {
+  if (last_alt_sep != nullptr &&
+      (last_sep == nullptr || last_alt_sep > last_sep)) {
     return last_alt_sep;
   }
 #endif
@@ -8420,9 +9430,6 @@
 // root directory per disk drive.)
 bool FilePath::IsRootDirectory() const {
 #if GTEST_OS_WINDOWS
-  // TODO(wan@google.com): on Windows a network share like
-  // \\server\share can be a root directory, although it cannot be the
-  // current directory.  Handle this properly.
   return pathname_.length() == 3 && IsAbsolutePath();
 #else
   return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
@@ -8494,7 +9501,7 @@
 #if GTEST_OS_WINDOWS_MOBILE
   FilePath removed_sep(this->RemoveTrailingPathSeparator());
   LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
-  int result = CreateDirectory(unicode, NULL) ? 0 : -1;
+  int result = CreateDirectory(unicode, nullptr) ? 0 : -1;
   delete [] unicode;
 #elif GTEST_OS_WINDOWS
   int result = _mkdir(pathname_.c_str());
@@ -8520,9 +9527,8 @@
 // Removes any redundant separators that might be in the pathname.
 // For example, "bar///foo" becomes "bar/foo". Does not eliminate other
 // redundancies that might be in a pathname involving "." or "..".
-// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
 void FilePath::Normalize() {
-  if (pathname_.c_str() == NULL) {
+  if (pathname_.c_str() == nullptr) {
     pathname_ = "";
     return;
   }
@@ -8553,6 +9559,155 @@
 
 }  // namespace internal
 }  // namespace testing
+// Copyright 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.
+
+// The Google C++ Testing and Mocking Framework (Google Test)
+//
+// This file implements just enough of the matcher interface to allow
+// EXPECT_DEATH and friends to accept a matcher argument.
+
+
+#include <string>
+
+namespace testing {
+
+// Constructs a matcher that matches a const std::string& whose value is
+// equal to s.
+Matcher<const std::string&>::Matcher(const std::string& s) { *this = Eq(s); }
+
+#if GTEST_HAS_GLOBAL_STRING
+// Constructs a matcher that matches a const std::string& whose value is
+// equal to s.
+Matcher<const std::string&>::Matcher(const ::string& s) {
+  *this = Eq(static_cast<std::string>(s));
+}
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+// Constructs a matcher that matches a const std::string& whose value is
+// equal to s.
+Matcher<const std::string&>::Matcher(const char* s) {
+  *this = Eq(std::string(s));
+}
+
+// Constructs a matcher that matches a std::string whose value is equal to
+// s.
+Matcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); }
+
+#if GTEST_HAS_GLOBAL_STRING
+// Constructs a matcher that matches a std::string whose value is equal to
+// s.
+Matcher<std::string>::Matcher(const ::string& s) {
+  *this = Eq(static_cast<std::string>(s));
+}
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+// Constructs a matcher that matches a std::string whose value is equal to
+// s.
+Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); }
+
+#if GTEST_HAS_GLOBAL_STRING
+// Constructs a matcher that matches a const ::string& whose value is
+// equal to s.
+Matcher<const ::string&>::Matcher(const std::string& s) {
+  *this = Eq(static_cast<::string>(s));
+}
+
+// Constructs a matcher that matches a const ::string& whose value is
+// equal to s.
+Matcher<const ::string&>::Matcher(const ::string& s) { *this = Eq(s); }
+
+// Constructs a matcher that matches a const ::string& whose value is
+// equal to s.
+Matcher<const ::string&>::Matcher(const char* s) { *this = Eq(::string(s)); }
+
+// Constructs a matcher that matches a ::string whose value is equal to s.
+Matcher<::string>::Matcher(const std::string& s) {
+  *this = Eq(static_cast<::string>(s));
+}
+
+// Constructs a matcher that matches a ::string whose value is equal to s.
+Matcher<::string>::Matcher(const ::string& s) { *this = Eq(s); }
+
+// Constructs a matcher that matches a string whose value is equal to s.
+Matcher<::string>::Matcher(const char* s) { *this = Eq(::string(s)); }
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_ABSL
+// Constructs a matcher that matches a const absl::string_view& whose value is
+// equal to s.
+Matcher<const absl::string_view&>::Matcher(const std::string& s) {
+  *this = Eq(s);
+}
+
+#if GTEST_HAS_GLOBAL_STRING
+// Constructs a matcher that matches a const absl::string_view& whose value is
+// equal to s.
+Matcher<const absl::string_view&>::Matcher(const ::string& s) { *this = Eq(s); }
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+// Constructs a matcher that matches a const absl::string_view& whose value is
+// equal to s.
+Matcher<const absl::string_view&>::Matcher(const char* s) {
+  *this = Eq(std::string(s));
+}
+
+// Constructs a matcher that matches a const absl::string_view& whose value is
+// equal to s.
+Matcher<const absl::string_view&>::Matcher(absl::string_view s) {
+  *this = Eq(std::string(s));
+}
+
+// Constructs a matcher that matches a absl::string_view whose value is equal to
+// s.
+Matcher<absl::string_view>::Matcher(const std::string& s) { *this = Eq(s); }
+
+#if GTEST_HAS_GLOBAL_STRING
+// Constructs a matcher that matches a absl::string_view whose value is equal to
+// s.
+Matcher<absl::string_view>::Matcher(const ::string& s) { *this = Eq(s); }
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+// Constructs a matcher that matches a absl::string_view whose value is equal to
+// s.
+Matcher<absl::string_view>::Matcher(const char* s) {
+  *this = Eq(std::string(s));
+}
+
+// Constructs a matcher that matches a absl::string_view whose value is equal to
+// s.
+Matcher<absl::string_view>::Matcher(absl::string_view s) {
+  *this = Eq(std::string(s));
+}
+#endif  // GTEST_HAS_ABSL
+
+}  // namespace testing
 // Copyright 2008, Google Inc.
 // All rights reserved.
 //
@@ -8581,21 +9736,24 @@
 // 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: wan@google.com (Zhanyong Wan)
+
 
 
 #include <limits.h>
-#include <stdlib.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <fstream>
+#include <memory>
 
 #if GTEST_OS_WINDOWS
 # include <windows.h>
 # include <io.h>
 # include <sys/stat.h>
 # include <map>  // Used in ThreadLocal.
+# ifdef _MSC_VER
+#  include <crtdbg.h>
+# endif  // _MSC_VER
 #else
 # include <unistd.h>
 #endif  // GTEST_OS_WINDOWS
@@ -8606,6 +9764,14 @@
 # include <mach/vm_map.h>
 #endif  // GTEST_OS_MAC
 
+#if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \
+    GTEST_OS_NETBSD || GTEST_OS_OPENBSD
+# include <sys/sysctl.h>
+# if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD
+#  include <sys/user.h>
+# endif
+#endif
+
 #if GTEST_OS_QNX
 # include <devctl.h>
 # include <fcntl.h>
@@ -8617,14 +9783,11 @@
 # include <sys/types.h>
 #endif  // GTEST_OS_AIX
 
+#if GTEST_OS_FUCHSIA
+# include <zircon/process.h>
+# include <zircon/syscalls.h>
+#endif  // GTEST_OS_FUCHSIA
 
-// Indicates that this translation unit is part of Google Test's
-// implementation.  It must come before gtest-internal-inl.h is
-// included, or there will be a compiler error.  This trick exists to
-// prevent the accidental inclusion of gtest-internal-inl.h in the
-// user's code.
-#define GTEST_IMPLEMENTATION_ 1
-#undef GTEST_IMPLEMENTATION_
 
 namespace testing {
 namespace internal {
@@ -8642,7 +9805,7 @@
 
 namespace {
 template <typename T>
-T ReadProcFileField(const string& filename, int field) {
+T ReadProcFileField(const std::string& filename, int field) {
   std::string dummy;
   std::ifstream file(filename.c_str());
   while (field-- > 0) {
@@ -8656,7 +9819,7 @@
 
 // Returns the number of active threads, or 0 when there is an error.
 size_t GetThreadCount() {
-  const string filename =
+  const std::string filename =
       (Message() << "/proc/" << getpid() << "/stat").GetString();
   return ReadProcFileField<int>(filename, 19);
 }
@@ -8680,6 +9843,81 @@
   }
 }
 
+#elif GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \
+      GTEST_OS_NETBSD
+
+#if GTEST_OS_NETBSD
+#undef KERN_PROC
+#define KERN_PROC KERN_PROC2
+#define kinfo_proc kinfo_proc2
+#endif
+
+#if GTEST_OS_DRAGONFLY
+#define KP_NLWP(kp) (kp.kp_nthreads)
+#elif GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD
+#define KP_NLWP(kp) (kp.ki_numthreads)
+#elif GTEST_OS_NETBSD
+#define KP_NLWP(kp) (kp.p_nlwps)
+#endif
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+size_t GetThreadCount() {
+  int mib[] = {
+    CTL_KERN,
+    KERN_PROC,
+    KERN_PROC_PID,
+    getpid(),
+#if GTEST_OS_NETBSD
+    sizeof(struct kinfo_proc),
+    1,
+#endif
+  };
+  u_int miblen = sizeof(mib) / sizeof(mib[0]);
+  struct kinfo_proc info;
+  size_t size = sizeof(info);
+  if (sysctl(mib, miblen, &info, &size, NULL, 0)) {
+    return 0;
+  }
+  return KP_NLWP(info);
+}
+#elif GTEST_OS_OPENBSD
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+size_t GetThreadCount() {
+  int mib[] = {
+    CTL_KERN,
+    KERN_PROC,
+    KERN_PROC_PID | KERN_PROC_SHOW_THREADS,
+    getpid(),
+    sizeof(struct kinfo_proc),
+    0,
+  };
+  u_int miblen = sizeof(mib) / sizeof(mib[0]);
+
+  // get number of structs
+  size_t size;
+  if (sysctl(mib, miblen, NULL, &size, NULL, 0)) {
+    return 0;
+  }
+  mib[5] = size / mib[4];
+
+  // populate array of structs
+  struct kinfo_proc info[mib[5]];
+  if (sysctl(mib, miblen, &info, &size, NULL, 0)) {
+    return 0;
+  }
+
+  // exclude empty members
+  int nthreads = 0;
+  for (int i = 0; i < size / mib[4]; i++) {
+    if (info[i].p_tid != -1)
+      nthreads++;
+  }
+  return nthreads;
+}
+
 #elif GTEST_OS_QNX
 
 // Returns the number of threads running in the process, or 0 to indicate that
@@ -8691,7 +9929,7 @@
   }
   procfs_info process_info;
   const int status =
-      devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL);
+      devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), nullptr);
   close(fd);
   if (status == EOK) {
     return static_cast<size_t>(process_info.num_threads);
@@ -8705,7 +9943,7 @@
 size_t GetThreadCount() {
   struct procentry64 entry;
   pid_t pid = getpid();
-  int status = getprocs64(&entry, sizeof(entry), NULL, 0, &pid, 1);
+  int status = getprocs64(&entry, sizeof(entry), nullptr, 0, &pid, 1);
   if (status == 1) {
     return entry.pi_thcount;
   } else {
@@ -8713,6 +9951,25 @@
   }
 }
 
+#elif GTEST_OS_FUCHSIA
+
+size_t GetThreadCount() {
+  int dummy_buffer;
+  size_t avail;
+  zx_status_t status = zx_object_get_info(
+      zx_process_self(),
+      ZX_INFO_PROCESS_THREADS,
+      &dummy_buffer,
+      0,
+      nullptr,
+      &avail);
+  if (status == ZX_OK) {
+    return avail;
+  } else {
+    return 0;
+  }
+}
+
 #else
 
 size_t GetThreadCount() {
@@ -8764,15 +10021,15 @@
 bool AutoHandle::IsCloseable() const {
   // Different Windows APIs may use either of these values to represent an
   // invalid handle.
-  return handle_ != NULL && handle_ != INVALID_HANDLE_VALUE;
+  return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;
 }
 
 Notification::Notification()
-    : event_(::CreateEvent(NULL,   // Default security attributes.
-                           TRUE,   // Do not reset automatically.
-                           FALSE,  // Initially unset.
-                           NULL)) {  // Anonymous event.
-  GTEST_CHECK_(event_.Get() != NULL);
+    : event_(::CreateEvent(nullptr,     // Default security attributes.
+                           TRUE,        // Do not reset automatically.
+                           FALSE,       // Initially unset.
+                           nullptr)) {  // Anonymous event.
+  GTEST_CHECK_(event_.Get() != nullptr);
 }
 
 void Notification::Notify() {
@@ -8795,13 +10052,10 @@
 Mutex::~Mutex() {
   // Static mutexes are leaked intentionally. It is not thread-safe to try
   // to clean them up.
-  // TODO(yukawa): Switch to Slim Reader/Writer (SRW) Locks, which requires
-  // nothing to clean it up but is available only on Vista and later.
-  // http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937.aspx
   if (type_ == kDynamic) {
     ::DeleteCriticalSection(critical_section_);
     delete critical_section_;
-    critical_section_ = NULL;
+    critical_section_ = nullptr;
   }
 }
 
@@ -8828,6 +10082,43 @@
       << "The current thread is not holding the mutex @" << this;
 }
 
+namespace {
+
+// Use the RAII idiom to flag mem allocs that are intentionally never
+// deallocated. The motivation is to silence the false positive mem leaks
+// that are reported by the debug version of MS's CRT which can only detect
+// if an alloc is missing a matching deallocation.
+// Example:
+//    MemoryIsNotDeallocated memory_is_not_deallocated;
+//    critical_section_ = new CRITICAL_SECTION;
+//
+class MemoryIsNotDeallocated
+{
+ public:
+  MemoryIsNotDeallocated() : old_crtdbg_flag_(0) {
+#ifdef _MSC_VER
+    old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+    // Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT
+    // doesn't report mem leak if there's no matching deallocation.
+    _CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF);
+#endif  //  _MSC_VER
+  }
+
+  ~MemoryIsNotDeallocated() {
+#ifdef _MSC_VER
+    // Restore the original _CRTDBG_ALLOC_MEM_DF flag
+    _CrtSetDbgFlag(old_crtdbg_flag_);
+#endif  //  _MSC_VER
+  }
+
+ private:
+  int old_crtdbg_flag_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(MemoryIsNotDeallocated);
+};
+
+}  // namespace
+
 // Initializes owner_thread_id_ and critical_section_ in static mutexes.
 void Mutex::ThreadSafeLazyInit() {
   // Dynamic mutexes are initialized in the constructor.
@@ -8838,7 +10129,11 @@
         // If critical_section_init_phase_ was 0 before the exchange, we
         // are the first to test it and need to perform the initialization.
         owner_thread_id_ = 0;
-        critical_section_ = new CRITICAL_SECTION;
+        {
+          // Use RAII to flag that following mem alloc is never deallocated.
+          MemoryIsNotDeallocated memory_is_not_deallocated;
+          critical_section_ = new CRITICAL_SECTION;
+        }
         ::InitializeCriticalSection(critical_section_);
         // Updates the critical_section_init_phase_ to 2 to signal
         // initialization complete.
@@ -8877,17 +10172,16 @@
                              Notification* thread_can_start) {
     ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start);
     DWORD thread_id;
-    // TODO(yukawa): Consider to use _beginthreadex instead.
     HANDLE thread_handle = ::CreateThread(
-        NULL,    // Default security.
-        0,       // Default stack size.
+        nullptr,  // Default security.
+        0,        // Default stack size.
         &ThreadWithParamSupport::ThreadMain,
-        param,   // Parameter to ThreadMainStatic
-        0x0,     // Default creation flags.
+        param,        // Parameter to ThreadMainStatic
+        0x0,          // Default creation flags.
         &thread_id);  // Need a valid pointer for the call to work under Win98.
-    GTEST_CHECK_(thread_handle != NULL) << "CreateThread failed with error "
-                                        << ::GetLastError() << ".";
-    if (thread_handle == NULL) {
+    GTEST_CHECK_(thread_handle != nullptr)
+        << "CreateThread failed with error " << ::GetLastError() << ".";
+    if (thread_handle == nullptr) {
       delete param;
     }
     return thread_handle;
@@ -8899,15 +10193,15 @@
         : runnable_(runnable),
           thread_can_start_(thread_can_start) {
     }
-    scoped_ptr<Runnable> runnable_;
+    std::unique_ptr<Runnable> runnable_;
     // Does not own.
     Notification* thread_can_start_;
   };
 
   static DWORD WINAPI ThreadMain(void* ptr) {
     // Transfers ownership.
-    scoped_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr));
-    if (param->thread_can_start_ != NULL)
+    std::unique_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr));
+    if (param->thread_can_start_ != nullptr)
       param->thread_can_start_->WaitForNotification();
     param->runnable_->Run();
     return 0;
@@ -8965,7 +10259,7 @@
           thread_local_values
               .insert(std::make_pair(
                   thread_local_instance,
-                  linked_ptr<ThreadLocalValueHolderBase>(
+                  std::shared_ptr<ThreadLocalValueHolderBase>(
                       thread_local_instance->NewValueForCurrentThread())))
               .first;
     }
@@ -8974,7 +10268,7 @@
 
   static void OnThreadLocalDestroyed(
       const ThreadLocalBase* thread_local_instance) {
-    std::vector<linked_ptr<ThreadLocalValueHolderBase> > value_holders;
+    std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;
     // Clean up the ThreadLocalValues data structure while holding the lock, but
     // defer the destruction of the ThreadLocalValueHolderBases.
     {
@@ -9002,7 +10296,7 @@
 
   static void OnThreadExit(DWORD thread_id) {
     GTEST_CHECK_(thread_id != 0) << ::GetLastError();
-    std::vector<linked_ptr<ThreadLocalValueHolderBase> > value_holders;
+    std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;
     // Clean up the ThreadIdToThreadLocals data structure while holding the
     // lock, but defer the destruction of the ThreadLocalValueHolderBases.
     {
@@ -9029,7 +10323,8 @@
  private:
   // In a particular thread, maps a ThreadLocal object to its value.
   typedef std::map<const ThreadLocalBase*,
-                   linked_ptr<ThreadLocalValueHolderBase> > ThreadLocalValues;
+                   std::shared_ptr<ThreadLocalValueHolderBase> >
+      ThreadLocalValues;
   // Stores all ThreadIdToThreadLocals having values in a thread, indexed by
   // thread's ID.
   typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
@@ -9044,18 +10339,17 @@
     HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION,
                                  FALSE,
                                  thread_id);
-    GTEST_CHECK_(thread != NULL);
-    // We need to to pass a valid thread ID pointer into CreateThread for it
+    GTEST_CHECK_(thread != nullptr);
+    // We need to pass a valid thread ID pointer into CreateThread for it
     // to work correctly under Win98.
     DWORD watcher_thread_id;
     HANDLE watcher_thread = ::CreateThread(
-        NULL,   // Default security.
-        0,      // Default stack size
+        nullptr,  // Default security.
+        0,        // Default stack size
         &ThreadLocalRegistryImpl::WatcherThreadFunc,
         reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
-        CREATE_SUSPENDED,
-        &watcher_thread_id);
-    GTEST_CHECK_(watcher_thread != NULL);
+        CREATE_SUSPENDED, &watcher_thread_id);
+    GTEST_CHECK_(watcher_thread != nullptr);
     // Give the watcher thread the same priority as ours to avoid being
     // blocked by it.
     ::SetThreadPriority(watcher_thread,
@@ -9080,7 +10374,8 @@
   // Returns map of thread local instances.
   static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
     mutex_.AssertHeld();
-    static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals;
+    MemoryIsNotDeallocated memory_is_not_deallocated;
+    static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals();
     return map;
   }
 
@@ -9174,7 +10469,7 @@
 // Returns true iff ch appears anywhere in str (excluding the
 // terminating '\0' character).
 bool IsInSet(char ch, const char* str) {
-  return ch != '\0' && strchr(str, ch) != NULL;
+  return ch != '\0' && strchr(str, ch) != nullptr;
 }
 
 // Returns true iff ch belongs to the given classification.  Unlike
@@ -9220,7 +10515,7 @@
 }
 
 // Helper function used by ValidateRegex() to format error messages.
-std::string FormatRegexSyntaxError(const char* regex, int index) {
+static std::string FormatRegexSyntaxError(const char* regex, int index) {
   return (Message() << "Syntax error at index " << index
           << " in simple regular expression \"" << regex << "\": ").GetString();
 }
@@ -9228,10 +10523,7 @@
 // Generates non-fatal failures and returns false if regex is invalid;
 // otherwise returns true.
 bool ValidateRegex(const char* regex) {
-  if (regex == NULL) {
-    // TODO(wan@google.com): fix the source file location in the
-    // assertion failures to match where the regex is used in user
-    // code.
+  if (regex == nullptr) {
     ADD_FAILURE() << "NULL is not a valid simple regular expression.";
     return false;
   }
@@ -9354,8 +10646,7 @@
 // exponential with respect to the regex length + the string length,
 // but usually it's must faster (often close to linear).
 bool MatchRegexAnywhere(const char* regex, const char* str) {
-  if (regex == NULL || str == NULL)
-    return false;
+  if (regex == nullptr || str == nullptr) return false;
 
   if (*regex == '^')
     return MatchRegexAtHead(regex + 1, str);
@@ -9388,8 +10679,8 @@
 
 // Initializes an RE from its string representation.
 void RE::Init(const char* regex) {
-  pattern_ = full_pattern_ = NULL;
-  if (regex != NULL) {
+  pattern_ = full_pattern_ = nullptr;
+  if (regex != nullptr) {
     pattern_ = posix::StrDup(regex);
   }
 
@@ -9427,7 +10718,7 @@
 // Formats a source file path and a line number as they would appear
 // in an error message from the compiler used to compile this code.
 GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
-  const std::string file_name(file == NULL ? kUnknownFile : file);
+  const std::string file_name(file == nullptr ? kUnknownFile : file);
 
   if (line < 0) {
     return file_name + ":";
@@ -9446,7 +10737,7 @@
 // to the file location it produces, unlike FormatFileLocation().
 GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(
     const char* file, int line) {
-  const std::string file_name(file == NULL ? kUnknownFile : file);
+  const std::string file_name(file == nullptr ? kUnknownFile : file);
 
   if (line < 0)
     return file_name;
@@ -9472,9 +10763,10 @@
     posix::Abort();
   }
 }
+
 // Disable Microsoft deprecation warnings for POSIX functions called from
 // this class (creat, dup, dup2, and close)
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
+GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
 
 #if GTEST_HAS_STREAM_REDIRECTION
 
@@ -9525,7 +10817,7 @@
     const int captured_fd = mkstemp(name_template);
     filename_ = name_template;
 # endif  // GTEST_OS_WINDOWS
-    fflush(NULL);
+    fflush(nullptr);
     dup2(captured_fd, fd_);
     close(captured_fd);
   }
@@ -9537,7 +10829,7 @@
   std::string GetCapturedString() {
     if (uncaptured_fd_ != -1) {
       // Restores the original stream.
-      fflush(NULL);
+      fflush(nullptr);
       dup2(uncaptured_fd_, fd_);
       close(uncaptured_fd_);
       uncaptured_fd_ = -1;
@@ -9558,14 +10850,15 @@
   GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
 };
 
-GTEST_DISABLE_MSC_WARNINGS_POP_()
+GTEST_DISABLE_MSC_DEPRECATED_POP_()
 
-static CapturedStream* g_captured_stderr = NULL;
-static CapturedStream* g_captured_stdout = NULL;
+static CapturedStream* g_captured_stderr = nullptr;
+static CapturedStream* g_captured_stdout = nullptr;
 
 // Starts capturing an output stream (stdout/stderr).
-void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
-  if (*stream != NULL) {
+static void CaptureStream(int fd, const char* stream_name,
+                          CapturedStream** stream) {
+  if (*stream != nullptr) {
     GTEST_LOG_(FATAL) << "Only one " << stream_name
                       << " capturer can exist at a time.";
   }
@@ -9573,11 +10866,11 @@
 }
 
 // Stops capturing the output stream and returns the captured string.
-std::string GetCapturedStream(CapturedStream** captured_stream) {
+static std::string GetCapturedStream(CapturedStream** captured_stream) {
   const std::string content = (*captured_stream)->GetCapturedString();
 
   delete *captured_stream;
-  *captured_stream = NULL;
+  *captured_stream = nullptr;
 
   return content;
 }
@@ -9604,23 +10897,9 @@
 
 #endif  // GTEST_HAS_STREAM_REDIRECTION
 
-std::string TempDir() {
-#if GTEST_OS_WINDOWS_MOBILE
-  return "\\temp\\";
-#elif GTEST_OS_WINDOWS
-  const char* temp_dir = posix::GetEnv("TEMP");
-  if (temp_dir == NULL || temp_dir[0] == '\0')
-    return "\\temp\\";
-  else if (temp_dir[strlen(temp_dir) - 1] == '\\')
-    return temp_dir;
-  else
-    return std::string(temp_dir) + "\\";
-#elif GTEST_OS_LINUX_ANDROID
-  return "/sdcard/";
-#else
-  return "/tmp/";
-#endif  // GTEST_OS_WINDOWS_MOBILE
-}
+
+
+
 
 size_t GetFileSize(FILE* file) {
   fseek(file, 0, SEEK_END);
@@ -9650,22 +10929,37 @@
 }
 
 #if GTEST_HAS_DEATH_TEST
+static const std::vector<std::string>* g_injected_test_argvs =
+    nullptr;  // Owned.
 
-static const ::std::vector<testing::internal::string>* g_injected_test_argvs =
-                                        NULL;  // Owned.
-
-void SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {
-  if (g_injected_test_argvs != argvs)
-    delete g_injected_test_argvs;
-  g_injected_test_argvs = argvs;
-}
-
-const ::std::vector<testing::internal::string>& GetInjectableArgvs() {
-  if (g_injected_test_argvs != NULL) {
+std::vector<std::string> GetInjectableArgvs() {
+  if (g_injected_test_argvs != nullptr) {
     return *g_injected_test_argvs;
   }
   return GetArgvs();
 }
+
+void SetInjectableArgvs(const std::vector<std::string>* new_argvs) {
+  if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs;
+  g_injected_test_argvs = new_argvs;
+}
+
+void SetInjectableArgvs(const std::vector<std::string>& new_argvs) {
+  SetInjectableArgvs(
+      new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
+}
+
+#if GTEST_HAS_GLOBAL_STRING
+void SetInjectableArgvs(const std::vector< ::string>& new_argvs) {
+  SetInjectableArgvs(
+      new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
+}
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+void ClearInjectableArgvs() {
+  delete g_injected_test_argvs;
+  g_injected_test_argvs = nullptr;
+}
 #endif  // GTEST_HAS_DEATH_TEST
 
 #if GTEST_OS_WINDOWS_MOBILE
@@ -9697,7 +10991,7 @@
 // unchanged and returns false.
 bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
   // Parses the environment variable as a decimal integer.
-  char* end = NULL;
+  char* end = nullptr;
   const long long_value = strtol(str, &end, 10);  // NOLINT
 
   // Has strtol() consumed all characters in the string?
@@ -9740,11 +11034,12 @@
 bool BoolFromGTestEnv(const char* flag, bool default_value) {
 #if defined(GTEST_GET_BOOL_FROM_ENV_)
   return GTEST_GET_BOOL_FROM_ENV_(flag, default_value);
-#endif  // defined(GTEST_GET_BOOL_FROM_ENV_)
+#else
   const std::string env_var = FlagToEnvVar(flag);
   const char* const string_value = posix::GetEnv(env_var.c_str());
-  return string_value == NULL ?
-      default_value : strcmp(string_value, "0") != 0;
+  return string_value == nullptr ? default_value
+                                 : strcmp(string_value, "0") != 0;
+#endif  // defined(GTEST_GET_BOOL_FROM_ENV_)
 }
 
 // Reads and returns a 32-bit integer stored in the environment
@@ -9753,10 +11048,10 @@
 Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
 #if defined(GTEST_GET_INT32_FROM_ENV_)
   return GTEST_GET_INT32_FROM_ENV_(flag, default_value);
-#endif  // defined(GTEST_GET_INT32_FROM_ENV_)
+#else
   const std::string env_var = FlagToEnvVar(flag);
   const char* const string_value = posix::GetEnv(env_var.c_str());
-  if (string_value == NULL) {
+  if (string_value == nullptr) {
     // The environment variable is not set.
     return default_value;
   }
@@ -9771,37 +11066,36 @@
   }
 
   return result;
+#endif  // defined(GTEST_GET_INT32_FROM_ENV_)
+}
+
+// As a special case for the 'output' flag, if GTEST_OUTPUT is not
+// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build
+// system.  The value of XML_OUTPUT_FILE is a filename without the
+// "xml:" prefix of GTEST_OUTPUT.
+// Note that this is meant to be called at the call site so it does
+// not check that the flag is 'output'
+// In essence this checks an env variable called XML_OUTPUT_FILE
+// and if it is set we prepend "xml:" to its value, if it not set we return ""
+std::string OutputFlagAlsoCheckEnvVar(){
+  std::string default_value_for_output_flag = "";
+  const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE");
+  if (nullptr != xml_output_file_env) {
+    default_value_for_output_flag = std::string("xml:") + xml_output_file_env;
+  }
+  return default_value_for_output_flag;
 }
 
 // Reads and returns the string environment variable corresponding to
 // the given flag; if it's not set, returns default_value.
-std::string StringFromGTestEnv(const char* flag, const char* default_value) {
+const char* StringFromGTestEnv(const char* flag, const char* default_value) {
 #if defined(GTEST_GET_STRING_FROM_ENV_)
   return GTEST_GET_STRING_FROM_ENV_(flag, default_value);
-#endif  // defined(GTEST_GET_STRING_FROM_ENV_)
+#else
   const std::string env_var = FlagToEnvVar(flag);
-  const char* value = posix::GetEnv(env_var.c_str());
-  if (value != NULL) {
-    return value;
-  }
-
-  // As a special case for the 'output' flag, if GTEST_OUTPUT is not
-  // set, we look for XML_OUTPUT_FILE, which is set by the Bazel build
-  // system.  The value of XML_OUTPUT_FILE is a filename without the
-  // "xml:" prefix of GTEST_OUTPUT.
-  //
-  // The net priority order after flag processing is thus:
-  //   --gtest_output command line flag
-  //   GTEST_OUTPUT environment variable
-  //   XML_OUTPUT_FILE environment variable
-  //   'default_value'
-  if (strcmp(flag, "output") == 0) {
-    value = posix::GetEnv("XML_OUTPUT_FILE");
-    if (value != NULL) {
-      return std::string("xml:") + value;
-    }
-  }
-  return default_value;
+  const char* const value = posix::GetEnv(env_var.c_str());
+  return value == nullptr ? default_value : value;
+#endif  // defined(GTEST_GET_STRING_FROM_ENV_)
 }
 
 }  // namespace internal
@@ -9834,10 +11128,9 @@
 // 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: wan@google.com (Zhanyong Wan)
 
-// Google Test - The Google C++ Testing Framework
+
+// Google Test - The Google C++ Testing and Mocking Framework
 //
 // This file implements a universal value printer that can print a
 // value of any type T:
@@ -9850,8 +11143,8 @@
 // or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
 // defines Foo.
 
-#include <ctype.h>
 #include <stdio.h>
+#include <cctype>
 #include <cwchar>
 #include <ostream>  // NOLINT
 #include <string>
@@ -9895,7 +11188,6 @@
   // If the object size is bigger than kThreshold, we'll have to omit
   // some details by printing only the first and the last kChunkSize
   // bytes.
-  // TODO(wan): let the user control the threshold using a flag.
   if (count < kThreshold) {
     PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
   } else {
@@ -9929,7 +11221,7 @@
 // Depending on the value of a char (or wchar_t), we print it in one
 // of three formats:
 //   - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
-//   - as a hexidecimal escape sequence (e.g. '\x7F'), or
+//   - as a hexadecimal escape sequence (e.g. '\x7F'), or
 //   - as a special escape sequence (e.g. '\r', '\n').
 enum CharFormat {
   kAsIs,
@@ -9986,7 +11278,10 @@
         *os << static_cast<char>(c);
         return kAsIs;
       } else {
-        *os << "\\x" + String::FormatHexInt(static_cast<UnsignedChar>(c));
+        ostream::fmtflags flags = os->flags();
+        *os << "\\x" << std::hex << std::uppercase
+            << static_cast<int>(static_cast<UnsignedChar>(c));
+        os->flags(flags);
         return kHexEscape;
       }
   }
@@ -10033,7 +11328,7 @@
     return;
   *os << " (" << static_cast<int>(c);
 
-  // For more convenience, we print c's code again in hexidecimal,
+  // For more convenience, we print c's code again in hexadecimal,
   // unless c was already printed in the form '\x##' or the code is in
   // [1, 9].
   if (format == kHexEscape || (1 <= c && c <= 9)) {
@@ -10065,11 +11360,12 @@
 GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
 GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
 GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
-static void PrintCharsAsStringTo(
+static CharFormat PrintCharsAsStringTo(
     const CharType* begin, size_t len, ostream* os) {
   const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
   *os << kQuoteBegin;
   bool is_previous_hex = false;
+  CharFormat print_format = kAsIs;
   for (size_t index = 0; index < len; ++index) {
     const CharType cur = begin[index];
     if (is_previous_hex && IsXDigit(cur)) {
@@ -10079,8 +11375,13 @@
       *os << "\" " << kQuoteBegin;
     }
     is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
+    // Remember if any characters required hex escaping.
+    if (is_previous_hex) {
+      print_format = kHexEscape;
+    }
   }
   *os << "\"";
+  return print_format;
 }
 
 // Prints a (const) char/wchar_t array of 'len' elements, starting at address
@@ -10124,7 +11425,7 @@
 
 // Prints the given C string to the ostream.
 void PrintTo(const char* s, ostream* os) {
-  if (s == NULL) {
+  if (s == nullptr) {
     *os << "NULL";
   } else {
     *os << ImplicitCast_<const void*>(s) << " pointing to ";
@@ -10141,24 +11442,99 @@
 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
 // Prints the given wide C string to the ostream.
 void PrintTo(const wchar_t* s, ostream* os) {
-  if (s == NULL) {
+  if (s == nullptr) {
     *os << "NULL";
   } else {
     *os << ImplicitCast_<const void*>(s) << " pointing to ";
-    PrintCharsAsStringTo(s, std::wcslen(s), os);
+    PrintCharsAsStringTo(s, wcslen(s), os);
   }
 }
 #endif  // wchar_t is native
 
+namespace {
+
+bool ContainsUnprintableControlCodes(const char* str, size_t length) {
+  const unsigned char *s = reinterpret_cast<const unsigned char *>(str);
+
+  for (size_t i = 0; i < length; i++) {
+    unsigned char ch = *s++;
+    if (std::iscntrl(ch)) {
+        switch (ch) {
+        case '\t':
+        case '\n':
+        case '\r':
+          break;
+        default:
+          return true;
+        }
+      }
+  }
+  return false;
+}
+
+bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t<= 0xbf; }
+
+bool IsValidUTF8(const char* str, size_t length) {
+  const unsigned char *s = reinterpret_cast<const unsigned char *>(str);
+
+  for (size_t i = 0; i < length;) {
+    unsigned char lead = s[i++];
+
+    if (lead <= 0x7f) {
+      continue;  // single-byte character (ASCII) 0..7F
+    }
+    if (lead < 0xc2) {
+      return false;  // trail byte or non-shortest form
+    } else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) {
+      ++i;  // 2-byte character
+    } else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length &&
+               IsUTF8TrailByte(s[i]) &&
+               IsUTF8TrailByte(s[i + 1]) &&
+               // check for non-shortest form and surrogate
+               (lead != 0xe0 || s[i] >= 0xa0) &&
+               (lead != 0xed || s[i] < 0xa0)) {
+      i += 2;  // 3-byte character
+    } else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length &&
+               IsUTF8TrailByte(s[i]) &&
+               IsUTF8TrailByte(s[i + 1]) &&
+               IsUTF8TrailByte(s[i + 2]) &&
+               // check for non-shortest form
+               (lead != 0xf0 || s[i] >= 0x90) &&
+               (lead != 0xf4 || s[i] < 0x90)) {
+      i += 3;  // 4-byte character
+    } else {
+      return false;
+    }
+  }
+  return true;
+}
+
+void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
+  if (!ContainsUnprintableControlCodes(str, length) &&
+      IsValidUTF8(str, length)) {
+    *os << "\n    As Text: \"" << str << "\"";
+  }
+}
+
+}  // anonymous namespace
+
 // Prints a ::string object.
 #if GTEST_HAS_GLOBAL_STRING
 void PrintStringTo(const ::string& s, ostream* os) {
-  PrintCharsAsStringTo(s.data(), s.size(), os);
+  if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
+    if (GTEST_FLAG(print_utf8)) {
+      ConditionalPrintAsText(s.data(), s.size(), os);
+    }
+  }
 }
 #endif  // GTEST_HAS_GLOBAL_STRING
 
 void PrintStringTo(const ::std::string& s, ostream* os) {
-  PrintCharsAsStringTo(s.data(), s.size(), os);
+  if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
+    if (GTEST_FLAG(print_utf8)) {
+      ConditionalPrintAsText(s.data(), s.size(), os);
+    }
+  }
 }
 
 // Prints a ::wstring object.
@@ -10205,19 +11581,10 @@
 // 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: mheule@google.com (Markus Heule)
-//
-// The Google C++ Testing Framework (Google Test)
 
+//
+// The Google C++ Testing and Mocking Framework (Google Test)
 
-// Indicates that this translation unit is part of Google Test's
-// implementation.  It must come before gtest-internal-inl.h is
-// included, or there will be a compiler error.  This trick exists to
-// prevent the accidental inclusion of gtest-internal-inl.h in the
-// user's code.
-#define GTEST_IMPLEMENTATION_ 1
-#undef GTEST_IMPLEMENTATION_
 
 namespace testing {
 
@@ -10227,18 +11594,21 @@
 // in it.
 std::string TestPartResult::ExtractSummary(const char* message) {
   const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
-  return stack_trace == NULL ? message :
-      std::string(message, stack_trace);
+  return stack_trace == nullptr ? message : std::string(message, stack_trace);
 }
 
 // Prints a TestPartResult object.
 std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
-  return os
-      << result.file_name() << ":" << result.line_number() << ": "
-      << (result.type() == TestPartResult::kSuccess ? "Success" :
-          result.type() == TestPartResult::kFatalFailure ? "Fatal failure" :
-          "Non-fatal failure") << ":\n"
-      << result.message() << std::endl;
+  return os << result.file_name() << ":" << result.line_number() << ": "
+            << (result.type() == TestPartResult::kSuccess
+                    ? "Success"
+                    : result.type() == TestPartResult::kSkip
+                          ? "Skipped"
+                          : result.type() == TestPartResult::kFatalFailure
+                                ? "Fatal failure"
+                                : "Non-fatal failure")
+            << ":\n"
+            << result.message() << std::endl;
 }
 
 // Appends a TestPartResult to the array.
@@ -10313,8 +11683,8 @@
 // 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: wan@google.com (Zhanyong Wan)
+
+
 
 
 namespace testing {
@@ -10333,7 +11703,7 @@
 static std::vector<std::string> SplitIntoTestNames(const char* src) {
   std::vector<std::string> name_vec;
   src = SkipSpaces(src);
-  for (; src != NULL; src = SkipComma(src)) {
+  for (; src != nullptr; src = SkipComma(src)) {
     name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src)));
   }
   return name_vec;
@@ -10342,7 +11712,7 @@
 // Verifies that registered_tests match the test names in
 // registered_tests_; returns registered_tests if successful, or
 // aborts the program otherwise.
-const char* TypedTestCasePState::VerifyRegisteredTestNames(
+const char* TypedTestSuitePState::VerifyRegisteredTestNames(
     const char* file, int line, const char* registered_tests) {
   typedef RegisteredTestsMap::const_iterator RegisteredTestIter;
   registered_ = true;
@@ -10374,7 +11744,7 @@
       tests.insert(name);
     } else {
       errors << "No test named " << name
-             << " can be found in this test case.\n";
+             << " can be found in this test suite.\n";
     }
   }
 
@@ -10429,8 +11799,7 @@
 // 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: wan@google.com (Zhanyong Wan)
+
 //
 // Google C++ Mocking Framework (Google Mock)
 //
@@ -10471,8 +11840,7 @@
 // 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: wan@google.com (Zhanyong Wan)
+
 
 // Google Mock - a framework for writing C++ mock classes.
 //
@@ -10513,18 +11881,18 @@
 
   // Conservative estimate on the lower/upper bound of the number of
   // calls allowed.
-  virtual int ConservativeLowerBound() const { return min_; }
-  virtual int ConservativeUpperBound() const { return max_; }
+  int ConservativeLowerBound() const override { return min_; }
+  int ConservativeUpperBound() const override { return max_; }
 
-  virtual bool IsSatisfiedByCallCount(int call_count) const {
+  bool IsSatisfiedByCallCount(int call_count) const override {
     return min_ <= call_count && call_count <= max_;
   }
 
-  virtual bool IsSaturatedByCallCount(int call_count) const {
+  bool IsSaturatedByCallCount(int call_count) const override {
     return call_count >= max_;
   }
 
-  virtual void DescribeTo(::std::ostream* os) const;
+  void DescribeTo(::std::ostream* os) const override;
 
  private:
   const int min_;
@@ -10534,7 +11902,7 @@
 };
 
 // Formats "n times" in a human-friendly way.
-inline internal::string FormatTimes(int n) {
+inline std::string FormatTimes(int n) {
   if (n == 1) {
     return "once";
   } else if (n == 2) {
@@ -10624,8 +11992,7 @@
 // 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: wan@google.com (Zhanyong Wan)
+
 
 // Google Mock - a framework for writing C++ mock classes.
 //
@@ -10641,12 +12008,31 @@
 namespace testing {
 namespace internal {
 
+// Joins a vector of strings as if they are fields of a tuple; returns
+// the joined string.
+GTEST_API_ std::string JoinAsTuple(const Strings& fields) {
+  switch (fields.size()) {
+    case 0:
+      return "";
+    case 1:
+      return fields[0];
+    default:
+      std::string result = "(" + fields[0];
+      for (size_t i = 1; i < fields.size(); i++) {
+        result += ", ";
+        result += fields[i];
+      }
+      result += ")";
+      return result;
+  }
+}
+
 // Converts an identifier name to a space-separated list of lower-case
 // words.  Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
 // treated as one word.  For example, both "FooBar123" and
 // "foo_bar_123" are converted to "foo bar 123".
-GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) {
-  string result;
+GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) {
+  std::string result;
   char prev_char = '\0';
   for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) {
     // We don't care about the current locale as the input is
@@ -10665,12 +12051,12 @@
 }
 
 // This class reports Google Mock failures as Google Test failures.  A
-// user can define another class in a similar fashion if he intends to
+// user can define another class in a similar fashion if they intend to
 // use Google Mock with a testing framework other than Google Test.
 class GoogleTestFailureReporter : public FailureReporterInterface {
  public:
-  virtual void ReportFailure(FailureType type, const char* file, int line,
-                             const string& message) {
+  void ReportFailure(FailureType type, const char* file, int line,
+                     const std::string& message) override {
     AssertHelper(type == kFatal ?
                  TestPartResult::kFatalFailure :
                  TestPartResult::kNonFatalFailure,
@@ -10722,8 +12108,7 @@
 // stack_frames_to_skip is treated as 0, since we don't know which
 // function calls will be inlined by the compiler and need to be
 // conservative.
-GTEST_API_ void Log(LogSeverity severity,
-                    const string& message,
+GTEST_API_ void Log(LogSeverity severity, const std::string& message,
                     int stack_frames_to_skip) {
   if (!LogIsVisible(severity))
     return;
@@ -10731,9 +12116,6 @@
   // Ensures that logs from different threads don't interleave.
   MutexLock l(&g_log_mutex);
 
-  // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a
-  // macro.
-
   if (severity == kWarning) {
     // Prints a GMOCK WARNING marker to make the warnings easily searchable.
     std::cout << "\nGMOCK WARNING:";
@@ -10764,6 +12146,18 @@
   std::cout << ::std::flush;
 }
 
+GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); }
+
+GTEST_API_ void IllegalDoDefault(const char* file, int line) {
+  internal::Assert(
+      false, file, line,
+      "You are using DoDefault() inside a composite action like "
+      "DoAll() or WithArgs().  This is not supported for technical "
+      "reasons.  Please instead spell out the default action, or "
+      "assign the default action to an Action variable and use "
+      "the variable in various places.");
+}
+
 }  // namespace internal
 }  // namespace testing
 // Copyright 2007, Google Inc.
@@ -10794,8 +12188,7 @@
 // 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: wan@google.com (Zhanyong Wan)
+
 
 // Google Mock - a framework for writing C++ mock classes.
 //
@@ -10804,98 +12197,23 @@
 
 
 #include <string.h>
+#include <iostream>
 #include <sstream>
 #include <string>
 
 namespace testing {
-
-// Constructs a matcher that matches a const string& whose value is
-// equal to s.
-Matcher<const internal::string&>::Matcher(const internal::string& s) {
-  *this = Eq(s);
-}
-
-// Constructs a matcher that matches a const string& whose value is
-// equal to s.
-Matcher<const internal::string&>::Matcher(const char* s) {
-  *this = Eq(internal::string(s));
-}
-
-// Constructs a matcher that matches a string whose value is equal to s.
-Matcher<internal::string>::Matcher(const internal::string& s) { *this = Eq(s); }
-
-// Constructs a matcher that matches a string whose value is equal to s.
-Matcher<internal::string>::Matcher(const char* s) {
-  *this = Eq(internal::string(s));
-}
-
-#if GTEST_HAS_STRING_PIECE_
-// Constructs a matcher that matches a const StringPiece& whose value is
-// equal to s.
-Matcher<const StringPiece&>::Matcher(const internal::string& s) {
-  *this = Eq(s);
-}
-
-// Constructs a matcher that matches a const StringPiece& whose value is
-// equal to s.
-Matcher<const StringPiece&>::Matcher(const char* s) {
-  *this = Eq(internal::string(s));
-}
-
-// Constructs a matcher that matches a const StringPiece& whose value is
-// equal to s.
-Matcher<const StringPiece&>::Matcher(StringPiece s) {
-  *this = Eq(s.ToString());
-}
-
-// Constructs a matcher that matches a StringPiece whose value is equal to s.
-Matcher<StringPiece>::Matcher(const internal::string& s) {
-  *this = Eq(s);
-}
-
-// Constructs a matcher that matches a StringPiece whose value is equal to s.
-Matcher<StringPiece>::Matcher(const char* s) {
-  *this = Eq(internal::string(s));
-}
-
-// Constructs a matcher that matches a StringPiece whose value is equal to s.
-Matcher<StringPiece>::Matcher(StringPiece s) {
-  *this = Eq(s.ToString());
-}
-#endif  // GTEST_HAS_STRING_PIECE_
-
 namespace internal {
 
-// Joins a vector of strings as if they are fields of a tuple; returns
-// the joined string.
-GTEST_API_ string JoinAsTuple(const Strings& fields) {
-  switch (fields.size()) {
-    case 0:
-      return "";
-    case 1:
-      return fields[0];
-    default:
-      string result = "(" + fields[0];
-      for (size_t i = 1; i < fields.size(); i++) {
-        result += ", ";
-        result += fields[i];
-      }
-      result += ")";
-      return result;
-  }
-}
-
 // Returns the description for a matcher defined using the MATCHER*()
 // macro where the user-supplied description string is "", if
 // 'negation' is false; otherwise returns the description of the
 // negation of the matcher.  'param_values' contains a list of strings
 // that are the print-out of the matcher's parameters.
-GTEST_API_ string FormatMatcherDescription(bool negation,
-                                           const char* matcher_name,
-                                           const Strings& param_values) {
-  string result = ConvertIdentifierNameToWords(matcher_name);
-  if (param_values.size() >= 1)
-    result += " " + JoinAsTuple(param_values);
+GTEST_API_ std::string FormatMatcherDescription(bool negation,
+                                                const char* matcher_name,
+                                                const Strings& param_values) {
+  std::string result = ConvertIdentifierNameToWords(matcher_name);
+  if (param_values.size() >= 1) result += " " + JoinAsTuple(param_values);
   return negation ? "not (" + result + ")" : result;
 }
 
@@ -10966,8 +12284,7 @@
   explicit MaxBipartiteMatchState(const MatchMatrix& graph)
       : graph_(&graph),
         left_(graph_->LhsSize(), kUnused),
-        right_(graph_->RhsSize(), kUnused) {
-  }
+        right_(graph_->RhsSize(), kUnused) {}
 
   // Returns the edges of a maximal match, each in the form {left, right}.
   ElementMatcherPairs Compute() {
@@ -11024,10 +12341,8 @@
   //
   bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {
     for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {
-      if ((*seen)[irhs])
-        continue;
-      if (!graph_->HasEdge(ilhs, irhs))
-        continue;
+      if ((*seen)[irhs]) continue;
+      if (!graph_->HasEdge(ilhs, irhs)) continue;
       // There's an available edge from ilhs to irhs.
       (*seen)[irhs] = 1;
       // Next a search is performed to determine whether
@@ -11054,7 +12369,7 @@
   // Each element of the left_ vector represents a left hand side node
   // (i.e. an element) and each element of right_ is a right hand side
   // node (i.e. a matcher). The values in the left_ vector indicate
-  // outflow from that node to a node on the the right_ side. The values
+  // outflow from that node to a node on the right_ side. The values
   // in the right_ indicate inflow, and specify which left_ node is
   // feeding that right_ node, if any. For example, left_[3] == 1 means
   // there's a flow from element #3 to matcher #1. Such a flow would also
@@ -11070,8 +12385,7 @@
 
 const size_t MaxBipartiteMatchState::kUnused;
 
-GTEST_API_ ElementMatcherPairs
-FindMaxBipartiteMatching(const MatchMatrix& g) {
+GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) {
   return MaxBipartiteMatchState(g).Compute();
 }
 
@@ -11080,7 +12394,7 @@
   typedef ElementMatcherPairs::const_iterator Iter;
   ::std::ostream& os = *stream;
   os << "{";
-  const char *sep = "";
+  const char* sep = "";
   for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
     os << sep << "\n  ("
        << "element #" << it->first << ", "
@@ -11090,38 +12404,6 @@
   os << "\n}";
 }
 
-// Tries to find a pairing, and explains the result.
-GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
-                            MatchResultListener* listener) {
-  ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
-
-  size_t max_flow = matches.size();
-  bool result = (max_flow == matrix.RhsSize());
-
-  if (!result) {
-    if (listener->IsInterested()) {
-      *listener << "where no permutation of the elements can "
-                   "satisfy all matchers, and the closest match is "
-                << max_flow << " of " << matrix.RhsSize()
-                << " matchers with the pairings:\n";
-      LogElementMatcherPairVec(matches, listener->stream());
-    }
-    return false;
-  }
-
-  if (matches.size() > 1) {
-    if (listener->IsInterested()) {
-      const char *sep = "where:\n";
-      for (size_t mi = 0; mi < matches.size(); ++mi) {
-        *listener << sep << " - element #" << matches[mi].first
-                  << " is matched by matcher #" << matches[mi].second;
-        sep = ",\n";
-      }
-    }
-  }
-  return true;
-}
-
 bool MatchMatrix::NextGraph() {
   for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
     for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
@@ -11145,9 +12427,9 @@
   }
 }
 
-string MatchMatrix::DebugString() const {
+std::string MatchMatrix::DebugString() const {
   ::std::stringstream ss;
-  const char *sep = "";
+  const char* sep = "";
   for (size_t i = 0; i < LhsSize(); ++i) {
     ss << sep;
     for (size_t j = 0; j < RhsSize(); ++j) {
@@ -11160,44 +12442,83 @@
 
 void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
     ::std::ostream* os) const {
-  if (matcher_describers_.empty()) {
-    *os << "is empty";
-    return;
+  switch (match_flags()) {
+    case UnorderedMatcherRequire::ExactMatch:
+      if (matcher_describers_.empty()) {
+        *os << "is empty";
+        return;
+      }
+      if (matcher_describers_.size() == 1) {
+        *os << "has " << Elements(1) << " and that element ";
+        matcher_describers_[0]->DescribeTo(os);
+        return;
+      }
+      *os << "has " << Elements(matcher_describers_.size())
+          << " and there exists some permutation of elements such that:\n";
+      break;
+    case UnorderedMatcherRequire::Superset:
+      *os << "a surjection from elements to requirements exists such that:\n";
+      break;
+    case UnorderedMatcherRequire::Subset:
+      *os << "an injection from elements to requirements exists such that:\n";
+      break;
   }
-  if (matcher_describers_.size() == 1) {
-    *os << "has " << Elements(1) << " and that element ";
-    matcher_describers_[0]->DescribeTo(os);
-    return;
-  }
-  *os << "has " << Elements(matcher_describers_.size())
-      << " and there exists some permutation of elements such that:\n";
+
   const char* sep = "";
   for (size_t i = 0; i != matcher_describers_.size(); ++i) {
-    *os << sep << " - element #" << i << " ";
+    *os << sep;
+    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+      *os << " - element #" << i << " ";
+    } else {
+      *os << " - an element ";
+    }
     matcher_describers_[i]->DescribeTo(os);
-    sep = ", and\n";
+    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+      sep = ", and\n";
+    } else {
+      sep = "\n";
+    }
   }
 }
 
 void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
     ::std::ostream* os) const {
-  if (matcher_describers_.empty()) {
-    *os << "isn't empty";
-    return;
+  switch (match_flags()) {
+    case UnorderedMatcherRequire::ExactMatch:
+      if (matcher_describers_.empty()) {
+        *os << "isn't empty";
+        return;
+      }
+      if (matcher_describers_.size() == 1) {
+        *os << "doesn't have " << Elements(1) << ", or has " << Elements(1)
+            << " that ";
+        matcher_describers_[0]->DescribeNegationTo(os);
+        return;
+      }
+      *os << "doesn't have " << Elements(matcher_describers_.size())
+          << ", or there exists no permutation of elements such that:\n";
+      break;
+    case UnorderedMatcherRequire::Superset:
+      *os << "no surjection from elements to requirements exists such that:\n";
+      break;
+    case UnorderedMatcherRequire::Subset:
+      *os << "no injection from elements to requirements exists such that:\n";
+      break;
   }
-  if (matcher_describers_.size() == 1) {
-    *os << "doesn't have " << Elements(1)
-        << ", or has " << Elements(1) << " that ";
-    matcher_describers_[0]->DescribeNegationTo(os);
-    return;
-  }
-  *os << "doesn't have " << Elements(matcher_describers_.size())
-      << ", or there exists no permutation of elements such that:\n";
   const char* sep = "";
   for (size_t i = 0; i != matcher_describers_.size(); ++i) {
-    *os << sep << " - element #" << i << " ";
+    *os << sep;
+    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+      *os << " - element #" << i << " ";
+    } else {
+      *os << " - an element ";
+    }
     matcher_describers_[i]->DescribeTo(os);
-    sep = ", and\n";
+    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+      sep = ", and\n";
+    } else {
+      sep = "\n";
+    }
   }
 }
 
@@ -11206,11 +12527,9 @@
 // and better error reporting.
 // Returns false, writing an explanation to 'listener', if and only
 // if the success criteria are not met.
-bool UnorderedElementsAreMatcherImplBase::
-VerifyAllElementsAndMatchersAreMatched(
-    const ::std::vector<string>& element_printouts,
-    const MatchMatrix& matrix,
-    MatchResultListener* listener) const {
+bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
+    const ::std::vector<std::string>& element_printouts,
+    const MatchMatrix& matrix, MatchResultListener* listener) const {
   bool result = true;
   ::std::vector<char> element_matched(matrix.LhsSize(), 0);
   ::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
@@ -11223,12 +12542,11 @@
     }
   }
 
-  {
+  if (match_flags() & UnorderedMatcherRequire::Superset) {
     const char* sep =
         "where the following matchers don't match any elements:\n";
     for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {
-      if (matcher_matched[mi])
-        continue;
+      if (matcher_matched[mi]) continue;
       result = false;
       if (listener->IsInterested()) {
         *listener << sep << "matcher #" << mi << ": ";
@@ -11238,7 +12556,7 @@
     }
   }
 
-  {
+  if (match_flags() & UnorderedMatcherRequire::Subset) {
     const char* sep =
         "where the following elements don't match any matchers:\n";
     const char* outer_sep = "";
@@ -11246,8 +12564,7 @@
       outer_sep = "\nand ";
     }
     for (size_t ei = 0; ei < element_matched.size(); ++ei) {
-      if (element_matched[ei])
-        continue;
+      if (element_matched[ei]) continue;
       result = false;
       if (listener->IsInterested()) {
         *listener << outer_sep << sep << "element #" << ei << ": "
@@ -11260,6 +12577,47 @@
   return result;
 }
 
+bool UnorderedElementsAreMatcherImplBase::FindPairing(
+    const MatchMatrix& matrix, MatchResultListener* listener) const {
+  ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
+
+  size_t max_flow = matches.size();
+  if ((match_flags() & UnorderedMatcherRequire::Superset) &&
+      max_flow < matrix.RhsSize()) {
+    if (listener->IsInterested()) {
+      *listener << "where no permutation of the elements can satisfy all "
+                   "matchers, and the closest match is "
+                << max_flow << " of " << matrix.RhsSize()
+                << " matchers with the pairings:\n";
+      LogElementMatcherPairVec(matches, listener->stream());
+    }
+    return false;
+  }
+  if ((match_flags() & UnorderedMatcherRequire::Subset) &&
+      max_flow < matrix.LhsSize()) {
+    if (listener->IsInterested()) {
+      *listener
+          << "where not all elements can be matched, and the closest match is "
+          << max_flow << " of " << matrix.RhsSize()
+          << " matchers with the pairings:\n";
+      LogElementMatcherPairVec(matches, listener->stream());
+    }
+    return false;
+  }
+
+  if (matches.size() > 1) {
+    if (listener->IsInterested()) {
+      const char* sep = "where:\n";
+      for (size_t mi = 0; mi < matches.size(); ++mi) {
+        *listener << sep << " - element #" << matches[mi].first
+                  << " is matched by matcher #" << matches[mi].second;
+        sep = ",\n";
+      }
+    }
+  }
+  return true;
+}
+
 }  // namespace internal
 }  // namespace testing
 // Copyright 2007, Google Inc.
@@ -11290,8 +12648,7 @@
 // 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: wan@google.com (Zhanyong Wan)
+
 
 // Google Mock - a framework for writing C++ mock classes.
 //
@@ -11302,13 +12659,24 @@
 #include <stdlib.h>
 #include <iostream>  // NOLINT
 #include <map>
+#include <memory>
 #include <set>
 #include <string>
+#include <vector>
 
 #if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
 # include <unistd.h>  // NOLINT
 #endif
 
+// Silence C4800 (C4800: 'int *const ': forcing value
+// to bool 'true' or 'false') for MSVC 15
+#ifdef _MSC_VER
+#if _MSC_VER == 1900
+#  pragma warning(push)
+#  pragma warning(disable:4800)
+#endif
+#endif
+
 namespace testing {
 namespace internal {
 
@@ -11319,16 +12687,15 @@
 // Logs a message including file and line number information.
 GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
                                 const char* file, int line,
-                                const string& message) {
+                                const std::string& message) {
   ::std::ostringstream s;
   s << file << ":" << line << ": " << message << ::std::endl;
   Log(severity, s.str(), 0);
 }
 
 // Constructs an ExpectationBase object.
-ExpectationBase::ExpectationBase(const char* a_file,
-                                 int a_line,
-                                 const string& a_source_text)
+ExpectationBase::ExpectationBase(const char* a_file, int a_line,
+                                 const std::string& a_source_text)
     : file_(a_file),
       line_(a_line),
       source_text_(a_source_text),
@@ -11361,12 +12728,19 @@
     return;
   }
 
-  for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
-       it != immediate_prerequisites_.end(); ++it) {
-    ExpectationBase* const prerequisite = it->expectation_base().get();
-    if (!prerequisite->is_retired()) {
-      prerequisite->RetireAllPreRequisites();
-      prerequisite->Retire();
+  ::std::vector<ExpectationBase*> expectations(1, this);
+  while (!expectations.empty()) {
+    ExpectationBase* exp = expectations.back();
+    expectations.pop_back();
+
+    for (ExpectationSet::const_iterator it =
+             exp->immediate_prerequisites_.begin();
+         it != exp->immediate_prerequisites_.end(); ++it) {
+      ExpectationBase* next = it->expectation_base().get();
+      if (!next->is_retired()) {
+        next->Retire();
+        expectations.push_back(next);
+      }
     }
   }
 }
@@ -11376,11 +12750,18 @@
 bool ExpectationBase::AllPrerequisitesAreSatisfied() const
     GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
   g_gmock_mutex.AssertHeld();
-  for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
-       it != immediate_prerequisites_.end(); ++it) {
-    if (!(it->expectation_base()->IsSatisfied()) ||
-        !(it->expectation_base()->AllPrerequisitesAreSatisfied()))
-      return false;
+  ::std::vector<const ExpectationBase*> expectations(1, this);
+  while (!expectations.empty()) {
+    const ExpectationBase* exp = expectations.back();
+    expectations.pop_back();
+
+    for (ExpectationSet::const_iterator it =
+             exp->immediate_prerequisites_.begin();
+         it != exp->immediate_prerequisites_.end(); ++it) {
+      const ExpectationBase* next = it->expectation_base().get();
+      if (!next->IsSatisfied()) return false;
+      expectations.push_back(next);
+    }
   }
   return true;
 }
@@ -11389,19 +12770,28 @@
 void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const
     GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
   g_gmock_mutex.AssertHeld();
-  for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
-       it != immediate_prerequisites_.end(); ++it) {
-    if (it->expectation_base()->IsSatisfied()) {
-      // If *it is satisfied and has a call count of 0, some of its
-      // pre-requisites may not be satisfied yet.
-      if (it->expectation_base()->call_count_ == 0) {
-        it->expectation_base()->FindUnsatisfiedPrerequisites(result);
+  ::std::vector<const ExpectationBase*> expectations(1, this);
+  while (!expectations.empty()) {
+    const ExpectationBase* exp = expectations.back();
+    expectations.pop_back();
+
+    for (ExpectationSet::const_iterator it =
+             exp->immediate_prerequisites_.begin();
+         it != exp->immediate_prerequisites_.end(); ++it) {
+      const ExpectationBase* next = it->expectation_base().get();
+
+      if (next->IsSatisfied()) {
+        // If *it is satisfied and has a call count of 0, some of its
+        // pre-requisites may not be satisfied yet.
+        if (next->call_count_ == 0) {
+          expectations.push_back(next);
+        }
+      } else {
+        // Now that we know next is unsatisfied, we are not so interested
+        // in whether its pre-requisites are satisfied.  Therefore we
+        // don't iterate into it here.
+        *result += *it;
       }
-    } else {
-      // Now that we know *it is unsatisfied, we are not so interested
-      // in whether its pre-requisites are satisfied.  Therefore we
-      // don't recursively call FindUnsatisfiedPrerequisites() here.
-      *result += *it;
     }
   }
 }
@@ -11505,7 +12895,7 @@
 
 // Reports an uninteresting call (whose description is in msg) in the
 // manner specified by 'reaction'.
-void ReportUninterestingCall(CallReaction reaction, const string& msg) {
+void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
   // Include a stack trace only if --gmock_verbose=info is specified.
   const int stack_frames_to_skip =
       GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1;
@@ -11516,20 +12906,22 @@
     case kWarn:
       Log(kWarning,
           msg +
-          "\nNOTE: You can safely ignore the above warning unless this "
-          "call should not happen.  Do not suppress it by blindly adding "
-          "an EXPECT_CALL() if you don't mean to enforce the call.  "
-          "See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#"
-          "knowing-when-to-expect for details.\n",
+              "\nNOTE: You can safely ignore the above warning unless this "
+              "call should not happen.  Do not suppress it by blindly adding "
+              "an EXPECT_CALL() if you don't mean to enforce the call.  "
+              "See "
+              "https://github.com/google/googletest/blob/master/googlemock/"
+              "docs/CookBook.md#"
+              "knowing-when-to-expect for details.\n",
           stack_frames_to_skip);
       break;
     default:  // FAIL
-      Expect(false, NULL, -1, msg);
+      Expect(false, nullptr, -1, msg);
   }
 }
 
 UntypedFunctionMockerBase::UntypedFunctionMockerBase()
-    : mock_obj_(NULL), name_("") {}
+    : mock_obj_(nullptr), name_("") {}
 
 UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
 
@@ -11568,7 +12960,7 @@
     // We protect mock_obj_ under g_gmock_mutex in case this mock
     // function is called from two threads concurrently.
     MutexLock l(&g_gmock_mutex);
-    Assert(mock_obj_ != NULL, __FILE__, __LINE__,
+    Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
            "MockObject() must not be called before RegisterOwner() or "
            "SetOwnerAndName() has been called.");
     mock_obj = mock_obj_;
@@ -11585,7 +12977,7 @@
     // We protect name_ under g_gmock_mutex in case this mock
     // function is called from two threads concurrently.
     MutexLock l(&g_gmock_mutex);
-    Assert(name_ != NULL, __FILE__, __LINE__,
+    Assert(name_ != nullptr, __FILE__, __LINE__,
            "Name() must not be called before SetOwnerAndName() has "
            "been called.");
     name = name_;
@@ -11596,9 +12988,10 @@
 // Calculates the result of invoking this mock function with the given
 // arguments, prints it, and returns it.  The caller is responsible
 // for deleting the result.
-UntypedActionResultHolderBase*
-UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
-    GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith(
+    void* const untyped_args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+  // See the definition of untyped_expectations_ for why access to it
+  // is unprotected here.
   if (untyped_expectations_.size() == 0) {
     // No expectation is set on this mock method - we have an
     // uninteresting call.
@@ -11615,18 +13008,21 @@
     // the behavior of ReportUninterestingCall().
     const bool need_to_report_uninteresting_call =
         // If the user allows this uninteresting call, we print it
-        // only when he wants informational messages.
+        // only when they want informational messages.
         reaction == kAllow ? LogIsVisible(kInfo) :
-        // If the user wants this to be a warning, we print it only
-        // when he wants to see warnings.
-        reaction == kWarn ? LogIsVisible(kWarning) :
-        // Otherwise, the user wants this to be an error, and we
-        // should always print detailed information in the error.
-        true;
+                           // If the user wants this to be a warning, we print
+                           // it only when they want to see warnings.
+            reaction == kWarn
+                ? LogIsVisible(kWarning)
+                :
+                // Otherwise, the user wants this to be an error, and we
+                // should always print detailed information in the error.
+                true;
 
     if (!need_to_report_uninteresting_call) {
       // Perform the action without printing the call information.
-      return this->UntypedPerformDefaultAction(untyped_args, "");
+      return this->UntypedPerformDefaultAction(
+          untyped_args, "Function call: " + std::string(Name()));
     }
 
     // Warns about the uninteresting call.
@@ -11638,8 +13034,7 @@
         this->UntypedPerformDefaultAction(untyped_args, ss.str());
 
     // Prints the function result.
-    if (result != NULL)
-      result->PrintAsActionResult(&ss);
+    if (result != nullptr) result->PrintAsActionResult(&ss);
 
     ReportUninterestingCall(reaction, ss.str());
     return result;
@@ -11649,7 +13044,7 @@
   ::std::stringstream ss;
   ::std::stringstream why;
   ::std::stringstream loc;
-  const void* untyped_action = NULL;
+  const void* untyped_action = nullptr;
 
   // The UntypedFindMatchingExpectation() function acquires and
   // releases g_gmock_mutex.
@@ -11657,7 +13052,7 @@
       this->UntypedFindMatchingExpectation(
           untyped_args, &untyped_action, &is_excessive,
           &ss, &why);
-  const bool found = untyped_expectation != NULL;
+  const bool found = untyped_expectation != nullptr;
 
   // True iff we need to print the call's arguments and return value.
   // This definition must be kept in sync with the uses of Expect()
@@ -11666,10 +13061,9 @@
       !found || is_excessive || LogIsVisible(kInfo);
   if (!need_to_report_call) {
     // Perform the action without printing the call information.
-    return
-        untyped_action == NULL ?
-        this->UntypedPerformDefaultAction(untyped_args, "") :
-        this->UntypedPerformAction(untyped_action, untyped_args);
+    return untyped_action == nullptr
+               ? this->UntypedPerformDefaultAction(untyped_args, "")
+               : this->UntypedPerformAction(untyped_action, untyped_args);
   }
 
   ss << "    Function call: " << Name();
@@ -11682,16 +13076,15 @@
   }
 
   UntypedActionResultHolderBase* const result =
-      untyped_action == NULL ?
-      this->UntypedPerformDefaultAction(untyped_args, ss.str()) :
-      this->UntypedPerformAction(untyped_action, untyped_args);
-  if (result != NULL)
-    result->PrintAsActionResult(&ss);
+      untyped_action == nullptr
+          ? this->UntypedPerformDefaultAction(untyped_args, ss.str())
+          : this->UntypedPerformAction(untyped_action, untyped_args);
+  if (result != nullptr) result->PrintAsActionResult(&ss);
   ss << "\n" << why.str();
 
   if (!found) {
     // No expectation matches this call - reports a failure.
-    Expect(false, NULL, -1, ss.str());
+    Expect(false, nullptr, -1, ss.str());
   } else if (is_excessive) {
     // We had an upper-bound violation and the failure message is in ss.
     Expect(false, untyped_expectation->file(),
@@ -11708,6 +13101,8 @@
 // Returns an Expectation object that references and co-owns exp,
 // which must be an expectation on this mock function.
 Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
+  // See the definition of untyped_expectations_ for why access to it
+  // is unprotected here.
   for (UntypedExpectations::const_iterator it =
            untyped_expectations_.begin();
        it != untyped_expectations_.end(); ++it) {
@@ -11770,6 +13165,13 @@
   return expectations_met;
 }
 
+CallReaction intToCallReaction(int mock_behavior) {
+  if (mock_behavior >= kAllow && mock_behavior <= kFail) {
+    return static_cast<internal::CallReaction>(mock_behavior);
+  }
+  return kWarn;
+}
+
 }  // namespace internal
 
 // Class Mock.
@@ -11783,13 +13185,13 @@
 // expectations.
 struct MockObjectState {
   MockObjectState()
-      : first_used_file(NULL), first_used_line(-1), leakable(false) {}
+      : first_used_file(nullptr), first_used_line(-1), leakable(false) {}
 
   // Where in the source file an ON_CALL or EXPECT_CALL is first
   // invoked on this mock object.
   const char* first_used_file;
   int first_used_line;
-  ::std::string first_used_test_case;
+  ::std::string first_used_test_suite;
   ::std::string first_used_test;
   bool leakable;  // true iff it's OK to leak the object.
   FunctionMockers function_mockers;  // All registered methods of the object.
@@ -11809,9 +13211,6 @@
   // object alive.  Therefore we report any living object as test
   // failure, unless the user explicitly asked us to ignore it.
   ~MockObjectRegistry() {
-    // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is
-    // a macro.
-
     if (!GMOCK_FLAG(catch_leaked_mocks))
       return;
 
@@ -11821,7 +13220,7 @@
       if (it->second.leakable)  // The user said it's fine to leak this object.
         continue;
 
-      // TODO(wan@google.com): Print the type of the leaked object.
+      // FIXME: Print the type of the leaked object.
       // This can help the user identify the leaked object.
       std::cout << "\n";
       const MockObjectState& state = it->second;
@@ -11829,17 +13228,23 @@
                                                 state.first_used_line);
       std::cout << " ERROR: this mock object";
       if (state.first_used_test != "") {
-        std::cout << " (used in test " << state.first_used_test_case << "."
-             << state.first_used_test << ")";
+        std::cout << " (used in test " << state.first_used_test_suite << "."
+                  << state.first_used_test << ")";
       }
       std::cout << " should be deleted but never is. Its address is @"
            << it->first << ".";
       leaked_count++;
     }
     if (leaked_count > 0) {
-      std::cout << "\nERROR: " << leaked_count
-           << " leaked mock " << (leaked_count == 1 ? "object" : "objects")
-           << " found at program exit.\n";
+      std::cout << "\nERROR: " << leaked_count << " leaked mock "
+                << (leaked_count == 1 ? "object" : "objects")
+                << " found at program exit. Expectations on a mock object is "
+                   "verified when the object is destructed. Leaking a mock "
+                   "means that its expectations aren't verified, which is "
+                   "usually a test bug. If you really intend to leak a mock, "
+                   "you can suppress this error using "
+                   "testing::Mock::AllowLeak(mock_object), or you may use a "
+                   "fake or stub instead of a mock.\n";
       std::cout.flush();
       ::std::cerr.flush();
       // RUN_ALL_TESTS() has already returned when this destructor is
@@ -11910,7 +13315,8 @@
         GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
   internal::MutexLock l(&internal::g_gmock_mutex);
   return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
-      internal::kDefault : g_uninteresting_call_reaction[mock_obj];
+      internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) :
+      g_uninteresting_call_reaction[mock_obj];
 }
 
 // Tells Google Mock to ignore mock_obj when checking for leaked mock
@@ -11968,6 +13374,19 @@
   return expectations_met;
 }
 
+bool Mock::IsNaggy(void* mock_obj)
+    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
+  return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kWarn;
+}
+bool Mock::IsNice(void* mock_obj)
+    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
+  return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kAllow;
+}
+bool Mock::IsStrict(void* mock_obj)
+    GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
+  return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kFail;
+}
+
 // Registers a mock object and a mock method it owns.
 void Mock::Register(const void* mock_obj,
                     internal::UntypedFunctionMockerBase* mocker)
@@ -11984,16 +13403,13 @@
     GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
   internal::MutexLock l(&internal::g_gmock_mutex);
   MockObjectState& state = g_mock_object_registry.states()[mock_obj];
-  if (state.first_used_file == NULL) {
+  if (state.first_used_file == nullptr) {
     state.first_used_file = file;
     state.first_used_line = line;
     const TestInfo* const test_info =
         UnitTest::GetInstance()->current_test_info();
-    if (test_info != NULL) {
-      // TODO(wan@google.com): record the test case name when the
-      // ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or
-      // TearDownTestCase().
-      state.first_used_test_case = test_info->test_case_name();
+    if (test_info != nullptr) {
+      state.first_used_test_suite = test_info->test_suite_name();
       state.first_used_test = test_info->name();
     }
   }
@@ -12046,7 +13462,7 @@
 Expectation::Expectation() {}
 
 Expectation::Expectation(
-    const internal::linked_ptr<internal::ExpectationBase>& an_expectation_base)
+    const std::shared_ptr<internal::ExpectationBase>& an_expectation_base)
     : expectation_base_(an_expectation_base) {}
 
 Expectation::~Expectation() {}
@@ -12054,7 +13470,7 @@
 // Adds an expectation to a sequence.
 void Sequence::AddExpectation(const Expectation& expectation) const {
   if (*last_expectation_ != expectation) {
-    if (last_expectation_->expectation_base() != NULL) {
+    if (last_expectation_->expectation_base() != nullptr) {
       expectation.expectation_base()->immediate_prerequisites_
           += *last_expectation_;
     }
@@ -12064,7 +13480,7 @@
 
 // Creates the implicit sequence if there isn't one.
 InSequence::InSequence() {
-  if (internal::g_gmock_implicit_sequence.get() == NULL) {
+  if (internal::g_gmock_implicit_sequence.get() == nullptr) {
     internal::g_gmock_implicit_sequence.set(new Sequence);
     sequence_created_ = true;
   } else {
@@ -12077,11 +13493,17 @@
 InSequence::~InSequence() {
   if (sequence_created_) {
     delete internal::g_gmock_implicit_sequence.get();
-    internal::g_gmock_implicit_sequence.set(NULL);
+    internal::g_gmock_implicit_sequence.set(nullptr);
   }
 }
 
 }  // namespace testing
+
+#ifdef _MSC_VER
+#if _MSC_VER == 1900
+#  pragma warning(pop)
+#endif
+#endif
 // Copyright 2008, Google Inc.
 // All rights reserved.
 //
@@ -12110,15 +13532,11 @@
 // 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: wan@google.com (Zhanyong Wan)
+
 
 
 namespace testing {
 
-// TODO(wan@google.com): support using environment variables to
-// control the flag values, like what Google Test does.
-
 GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
                    "true iff Google Mock should report leaked mock objects "
                    "as failures.");
@@ -12130,6 +13548,13 @@
                      "  warning - prints warnings and errors.\n"
                      "  error   - prints errors only.");
 
+GMOCK_DEFINE_int32_(default_mock_behavior, 1,
+                    "Controls the default behavior of mocks."
+                    "  Valid values:\n"
+                    "  0 - by default, mocks act as NiceMocks.\n"
+                    "  1 - by default, mocks act as NaggyMocks.\n"
+                    "  2 - by default, mocks act as StrictMocks.");
+
 namespace internal {
 
 // Parses a string as a command line flag.  The string should have the
@@ -12141,12 +13566,12 @@
                                             const char* flag,
                                             bool def_optional) {
   // str and flag must not be NULL.
-  if (str == NULL || flag == NULL) return NULL;
+  if (str == nullptr || flag == nullptr) return nullptr;
 
   // The flag must start with "--gmock_".
   const std::string flag_str = std::string("--gmock_") + flag;
   const size_t flag_len = flag_str.length();
-  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
+  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
 
   // Skips the flag name.
   const char* flag_end = str + flag_len;
@@ -12159,7 +13584,7 @@
   // If def_optional is true and there are more characters after the
   // flag name, or if def_optional is false, there must be a '=' after
   // the flag name.
-  if (flag_end[0] != '=') return NULL;
+  if (flag_end[0] != '=') return nullptr;
 
   // Returns the string after "=".
   return flag_end + 1;
@@ -12176,7 +13601,7 @@
   const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
 
   // Aborts if the parsing failed.
-  if (value_str == NULL) return false;
+  if (value_str == nullptr) return false;
 
   // Converts the string value to a bool.
   *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
@@ -12195,13 +13620,26 @@
   const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
 
   // Aborts if the parsing failed.
-  if (value_str == NULL) return false;
+  if (value_str == nullptr) return false;
 
   // Sets *value to the value of the flag.
   *value = value_str;
   return true;
 }
 
+static bool ParseGoogleMockIntFlag(const char* str, const char* flag,
+                                   int* value) {
+  // Gets the value of the flag as a string.
+  const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
+
+  // Aborts if the parsing failed.
+  if (value_str == nullptr) return false;
+
+  // Sets *value to the value of the flag.
+  return ParseInt32(Message() << "The value of flag --" << flag,
+                    value_str, value);
+}
+
 // The internal implementation of InitGoogleMock().
 //
 // The type parameter CharType can be instantiated to either char or
@@ -12220,7 +13658,9 @@
     // Do we see a Google Mock flag?
     if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
                                 &GMOCK_FLAG(catch_leaked_mocks)) ||
-        ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
+        ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose)) ||
+        ParseGoogleMockIntFlag(arg, "default_mock_behavior",
+                               &GMOCK_FLAG(default_mock_behavior))) {
       // Yes.  Shift the remainder of the argv list left by one.  Note
       // that argv has (*argc + 1) elements, the last one always being
       // NULL.  The following loop moves the trailing NULL element as
@@ -12262,4 +13702,16 @@
   internal::InitGoogleMockImpl(argc, argv);
 }
 
+// This overloaded version can be used on Arduino/embedded platforms where
+// there is no argc/argv.
+GTEST_API_ void InitGoogleMock() {
+  // Since Arduino doesn't have a command line, fake out the argc/argv arguments
+  int argc = 1;
+  const auto arg0 = "dummy";
+  char* argv0 = const_cast<char*>(arg0);
+  char** argv = &argv0;
+
+  internal::InitGoogleMockImpl(&argc, argv);
+}
+
 }  // namespace testing
diff --git a/internal/ceres/gmock_main.cc b/internal/ceres/gmock_main.cc
index 5800dc0..92d850c 100644
--- a/internal/ceres/gmock_main.cc
+++ b/internal/ceres/gmock_main.cc
@@ -64,6 +64,6 @@
   // gflags, InitGoogleTest() (called by InitGoogleMock()) must be called
   // before ParseCommandLineFlags() to handle & remove them before gflags
   // parses the remaining flags.
-  CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
+  GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
   return RUN_ALL_TESTS();
 }
diff --git a/internal/ceres/gradient_checker.cc b/internal/ceres/gradient_checker.cc
index 411a67f..dadaaa0 100644
--- a/internal/ceres/gradient_checker.cc
+++ b/internal/ceres/gradient_checker.cc
@@ -56,7 +56,7 @@
 // the local space of the respective local parameterizations.
 bool EvaluateCostFunction(
     const ceres::CostFunction* function,
-    double const* const * parameters,
+    double const* const* parameters,
     const std::vector<const ceres::LocalParameterization*>&
         local_parameterizations,
     Vector* residuals,
@@ -95,8 +95,8 @@
   CHECK_NE(0, function->num_residuals());
   residuals->resize(function->num_residuals());
   residuals->setZero();
-  if (!function->Evaluate(parameters, residuals->data(),
-                          jacobian_data.data())) {
+  if (!function->Evaluate(
+          parameters, residuals->data(), jacobian_data.data())) {
     return false;
   }
 
@@ -109,20 +109,20 @@
       int local_size = local_parameterizations.at(i)->LocalSize();
       CHECK_EQ(jacobians->at(i).cols(), global_size);
       Matrix global_J_local(global_size, local_size);
-      local_parameterizations.at(i)->ComputeJacobian(
-          parameters[i], global_J_local.data());
+      local_parameterizations.at(i)->ComputeJacobian(parameters[i],
+                                                     global_J_local.data());
       local_jacobians->at(i).noalias() = jacobians->at(i) * global_J_local;
     }
   }
   return true;
 }
-} // namespace
+}  // namespace
 
 GradientChecker::GradientChecker(
-      const CostFunction* function,
-      const vector<const LocalParameterization*>* local_parameterizations,
-      const NumericDiffOptions& options) :
-        function_(function) {
+    const CostFunction* function,
+    const vector<const LocalParameterization*>* local_parameterizations,
+    const NumericDiffOptions& options)
+    : function_(function) {
   CHECK(function != nullptr);
   if (local_parameterizations != NULL) {
     local_parameterizations_ = *local_parameterizations;
@@ -130,10 +130,10 @@
     local_parameterizations_.resize(function->parameter_block_sizes().size(),
                                     NULL);
   }
-  DynamicNumericDiffCostFunction<CostFunction, CENTRAL>*
+  DynamicNumericDiffCostFunction<CostFunction, RIDDERS>*
       finite_diff_cost_function =
-      new DynamicNumericDiffCostFunction<CostFunction, CENTRAL>(
-          function, DO_NOT_TAKE_OWNERSHIP, options);
+          new DynamicNumericDiffCostFunction<CostFunction, RIDDERS>(
+              function, DO_NOT_TAKE_OWNERSHIP, options);
   finite_diff_cost_function_.reset(finite_diff_cost_function);
 
   const vector<int32_t>& parameter_block_sizes =
@@ -145,7 +145,7 @@
   finite_diff_cost_function->SetNumResiduals(function->num_residuals());
 }
 
-bool GradientChecker::Probe(double const* const * parameters,
+bool GradientChecker::Probe(double const* const* parameters,
                             double relative_precision,
                             ProbeResults* results_param) const {
   int num_residuals = function_->num_residuals();
@@ -171,8 +171,12 @@
   // Evaluate the derivative using the user supplied code.
   vector<Matrix>& jacobians = results->jacobians;
   vector<Matrix>& local_jacobians = results->local_jacobians;
-  if (!EvaluateCostFunction(function_, parameters, local_parameterizations_,
-                       &results->residuals, &jacobians, &local_jacobians)) {
+  if (!EvaluateCostFunction(function_,
+                            parameters,
+                            local_parameterizations_,
+                            &results->residuals,
+                            &jacobians,
+                            &local_jacobians)) {
     results->error_log = "Function evaluation with Jacobians failed.";
     results->return_value = false;
   }
@@ -181,10 +185,14 @@
   vector<Matrix>& numeric_jacobians = results->numeric_jacobians;
   vector<Matrix>& local_numeric_jacobians = results->local_numeric_jacobians;
   Vector finite_diff_residuals;
-  if (!EvaluateCostFunction(finite_diff_cost_function_.get(), parameters,
-                            local_parameterizations_, &finite_diff_residuals,
-                            &numeric_jacobians, &local_numeric_jacobians)) {
-    results->error_log += "\nFunction evaluation with numerical "
+  if (!EvaluateCostFunction(finite_diff_cost_function_.get(),
+                            parameters,
+                            local_parameterizations_,
+                            &finite_diff_residuals,
+                            &numeric_jacobians,
+                            &local_numeric_jacobians)) {
+    results->error_log +=
+        "\nFunction evaluation with numerical "
         "differentiation failed.";
     results->return_value = false;
   }
@@ -194,13 +202,13 @@
   }
 
   for (int i = 0; i < num_residuals; ++i) {
-    if (!IsClose(
-        results->residuals[i],
-        finite_diff_residuals[i],
-        relative_precision,
-        NULL,
-        NULL)) {
-      results->error_log = "Function evaluation with and without Jacobians "
+    if (!IsClose(results->residuals[i],
+                 finite_diff_residuals[i],
+                 relative_precision,
+                 NULL,
+                 NULL)) {
+      results->error_log =
+          "Function evaluation with and without Jacobians "
           "resulted in different residuals.";
       LOG(INFO) << results->residuals.transpose();
       LOG(INFO) << finite_diff_residuals.transpose();
@@ -219,7 +227,7 @@
   for (int k = 0; k < function_->parameter_block_sizes().size(); k++) {
     StringAppendF(&error_log,
                   "========== "
-                  "Jacobian for " "block %d: (%ld by %ld)) "
+                  "Jacobian for block %d: (%ld by %ld)) "
                   "==========\n",
                   k,
                   static_cast<long>(local_jacobians[k].rows()),
@@ -234,28 +242,33 @@
         double term_jacobian = local_jacobians[k](i, j);
         double finite_jacobian = local_numeric_jacobians[k](i, j);
         double relative_error, absolute_error;
-        bool bad_jacobian_entry =
-            !IsClose(term_jacobian,
-                     finite_jacobian,
-                     relative_precision,
-                     &relative_error,
-                     &absolute_error);
+        bool bad_jacobian_entry = !IsClose(term_jacobian,
+                                           finite_jacobian,
+                                           relative_precision,
+                                           &relative_error,
+                                           &absolute_error);
         worst_relative_error = std::max(worst_relative_error, relative_error);
 
         StringAppendF(&error_log,
                       "%6d %4d %4d %17g %17g %17g %17g %17g %17g",
-                      k, i, j,
-                      term_jacobian, finite_jacobian,
-                      absolute_error, relative_error,
+                      k,
+                      i,
+                      j,
+                      term_jacobian,
+                      finite_jacobian,
+                      absolute_error,
+                      relative_error,
                       parameters[k][j],
                       results->residuals[i]);
 
         if (bad_jacobian_entry) {
           num_bad_jacobian_components++;
-          StringAppendF(
-              &error_log,
-              " ------ (%d,%d,%d) Relative error worse than %g",
-              k, i, j, relative_precision);
+          StringAppendF(&error_log,
+                        " ------ (%d,%d,%d) Relative error worse than %g",
+                        k,
+                        i,
+                        j,
+                        relative_precision);
         }
         error_log += "\n";
       }
@@ -264,11 +277,12 @@
 
   // Since there were some bad errors, dump comprehensive debug info.
   if (num_bad_jacobian_components) {
-    string header = StringPrintf("\nDetected %d bad Jacobian component(s). "
+    string header = StringPrintf(
+        "\nDetected %d bad Jacobian component(s). "
         "Worst relative error was %g.\n",
         num_bad_jacobian_components,
         worst_relative_error);
-     results->error_log = header + "\n" + error_log;
+    results->error_log = header + "\n" + error_log;
     return false;
   }
   return true;
diff --git a/internal/ceres/gradient_checker_test.cc b/internal/ceres/gradient_checker_test.cc
index 92d7b26..31dc97b 100644
--- a/internal/ceres/gradient_checker_test.cc
+++ b/internal/ceres/gradient_checker_test.cc
@@ -48,6 +48,7 @@
 namespace internal {
 
 using std::vector;
+const double kTolerance = 1e-12;
 
 // We pick a (non-quadratic) function whose derivative are easy:
 //
@@ -154,7 +155,7 @@
         if (jacobians[j]) {
           for (int u = 0; u < parameter_block_sizes()[j]; ++u) {
             // See comments before class.
-            jacobians[j][u] = -f * a_[j][u] + 0.001;
+            jacobians[j][u] = -f * a_[j][u] + kTolerance;
           }
         }
       }
@@ -168,12 +169,10 @@
   vector<vector<double>> a_;  // our vectors.
 };
 
-const double kTolerance = 1e-6;
-
-void CheckDimensions(const GradientChecker::ProbeResults& results,
-                     const std::vector<int>& parameter_sizes,
-                     const std::vector<int>& local_parameter_sizes,
-                     int residual_size) {
+static void CheckDimensions(const GradientChecker::ProbeResults& results,
+                            const std::vector<int>& parameter_sizes,
+                            const std::vector<int>& local_parameter_sizes,
+                            int residual_size) {
   CHECK_EQ(parameter_sizes.size(), local_parameter_sizes.size());
   int num_parameters = parameter_sizes.size();
   ASSERT_EQ(residual_size, results.residuals.size());
@@ -219,9 +218,9 @@
   // Test that Probe returns true for correct Jacobians.
   GoodTestTerm good_term(num_parameters, parameter_sizes.data());
   GradientChecker good_gradient_checker(&good_term, NULL, numeric_diff_options);
-  EXPECT_TRUE(good_gradient_checker.Probe(parameters.get(), kTolerance, NULL));
+  EXPECT_TRUE(good_gradient_checker.Probe(parameters.data(), kTolerance, NULL));
   EXPECT_TRUE(
-      good_gradient_checker.Probe(parameters.get(), kTolerance, &results))
+      good_gradient_checker.Probe(parameters.data(), kTolerance, &results))
       << results.error_log;
 
   // Check that results contain sensible data.
@@ -233,9 +232,10 @@
 
   // Test that if the cost function return false, Probe should return false.
   good_term.SetReturnValue(false);
-  EXPECT_FALSE(good_gradient_checker.Probe(parameters.get(), kTolerance, NULL));
   EXPECT_FALSE(
-      good_gradient_checker.Probe(parameters.get(), kTolerance, &results))
+      good_gradient_checker.Probe(parameters.data(), kTolerance, NULL));
+  EXPECT_FALSE(
+      good_gradient_checker.Probe(parameters.data(), kTolerance, &results))
       << results.error_log;
 
   // Check that results contain sensible data.
@@ -252,9 +252,9 @@
   // Test that Probe returns false for incorrect Jacobians.
   BadTestTerm bad_term(num_parameters, parameter_sizes.data());
   GradientChecker bad_gradient_checker(&bad_term, NULL, numeric_diff_options);
-  EXPECT_FALSE(bad_gradient_checker.Probe(parameters.get(), kTolerance, NULL));
+  EXPECT_FALSE(bad_gradient_checker.Probe(parameters.data(), kTolerance, NULL));
   EXPECT_FALSE(
-      bad_gradient_checker.Probe(parameters.get(), kTolerance, &results));
+      bad_gradient_checker.Probe(parameters.data(), kTolerance, &results));
 
   // Check that results contain sensible data.
   ASSERT_EQ(results.return_value, true);
@@ -264,7 +264,7 @@
   EXPECT_FALSE(results.error_log.empty());
 
   // Setting a high threshold should make the test pass.
-  EXPECT_TRUE(bad_gradient_checker.Probe(parameters.get(), 1.0, &results));
+  EXPECT_TRUE(bad_gradient_checker.Probe(parameters.data(), 1.0, &results));
 
   // Check that results contain sensible data.
   ASSERT_EQ(results.return_value, true);
@@ -289,9 +289,9 @@
     set_num_residuals(residuals_offset_.size());
   }
 
-  virtual bool Evaluate(double const* const* parameter_ptrs,
-                        double* residuals_ptr,
-                        double** residual_J_params) const {
+  bool Evaluate(double const* const* parameter_ptrs,
+                double* residuals_ptr,
+                double** residual_J_params) const final {
     CHECK_GE(residual_J_params_.size(), 0.0);
     VectorRef residuals(residuals_ptr, residual_J_params_[0].rows());
     residuals = residuals_offset_;
@@ -346,28 +346,28 @@
  */
 class MatrixParameterization : public LocalParameterization {
  public:
-  virtual bool Plus(const double* x,
-                    const double* delta,
-                    double* x_plus_delta) const {
+  bool Plus(const double* x,
+            const double* delta,
+            double* x_plus_delta) const final {
     VectorRef(x_plus_delta, GlobalSize()) =
         ConstVectorRef(x, GlobalSize()) +
         (global_J_local * ConstVectorRef(delta, LocalSize()));
     return true;
   }
 
-  virtual bool ComputeJacobian(const double* /*x*/, double* jacobian) const {
+  bool ComputeJacobian(const double* /*x*/, double* jacobian) const final {
     MatrixRef(jacobian, GlobalSize(), LocalSize()) = global_J_local;
     return true;
   }
 
-  virtual int GlobalSize() const { return global_J_local.rows(); }
-  virtual int LocalSize() const { return global_J_local.cols(); }
+  int GlobalSize() const final { return global_J_local.rows(); }
+  int LocalSize() const final { return global_J_local.cols(); }
 
   Matrix global_J_local;
 };
 
 // Helper function to compare two Eigen matrices (used in the test below).
-void ExpectMatricesClose(Matrix p, Matrix q, double tolerance) {
+static void ExpectMatricesClose(Matrix p, Matrix q, double tolerance) {
   ASSERT_EQ(p.rows(), q.rows());
   ASSERT_EQ(p.cols(), q.cols());
   ExpectArraysClose(p.size(), p.data(), q.data(), tolerance);
diff --git a/internal/ceres/gradient_checking_cost_function.cc b/internal/ceres/gradient_checking_cost_function.cc
index 1afbec3..2eb6d62 100644
--- a/internal/ceres/gradient_checking_cost_function.cc
+++ b/internal/ceres/gradient_checking_cost_function.cc
@@ -38,6 +38,7 @@
 #include <string>
 #include <vector>
 
+#include "ceres/dynamic_numeric_diff_cost_function.h"
 #include "ceres/gradient_checker.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/parameter_block.h"
@@ -45,7 +46,6 @@
 #include "ceres/problem_impl.h"
 #include "ceres/program.h"
 #include "ceres/residual_block.h"
-#include "ceres/dynamic_numeric_diff_cost_function.h"
 #include "ceres/stringprintf.h"
 #include "ceres/types.h"
 #include "glog/logging.h"
@@ -81,20 +81,19 @@
     set_num_residuals(function->num_residuals());
   }
 
-  virtual ~GradientCheckingCostFunction() { }
+  virtual ~GradientCheckingCostFunction() {}
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     if (!jacobians) {
       // Nothing to check in this case; just forward.
       return function_->Evaluate(parameters, residuals, NULL);
     }
 
     GradientChecker::ProbeResults results;
-    bool okay = gradient_checker_.Probe(parameters,
-                                        relative_precision_,
-                                        &results);
+    bool okay =
+        gradient_checker_.Probe(parameters, relative_precision_, &results);
 
     // If the cost function returned false, there's nothing we can say about
     // the gradients.
@@ -117,8 +116,9 @@
     }
 
     if (!okay) {
-      std::string error_log = "Gradient Error detected!\nExtra info for "
-          "this residual: " + extra_info_ + "\n" + results.error_log;
+      std::string error_log =
+          "Gradient Error detected!\nExtra info for this residual: " +
+          extra_info_ + "\n" + results.error_log;
       callback_->SetGradientErrorDetected(error_log);
     }
     return true;
@@ -135,13 +135,12 @@
 }  // namespace
 
 GradientCheckingIterationCallback::GradientCheckingIterationCallback()
-    : gradient_error_detected_(false) {
-}
+    : gradient_error_detected_(false) {}
 
 CallbackReturnType GradientCheckingIterationCallback::operator()(
     const IterationSummary& summary) {
   if (gradient_error_detected_) {
-    LOG(ERROR)<< "Gradient error detected. Terminating solver.";
+    LOG(ERROR) << "Gradient error detected. Terminating solver.";
     return SOLVER_ABORT;
   }
   return SOLVER_CONTINUE;
@@ -166,7 +165,8 @@
   return new GradientCheckingCostFunction(cost_function,
                                           local_parameterizations,
                                           numeric_diff_options,
-                                          relative_precision, extra_info,
+                                          relative_precision,
+                                          extra_info,
                                           callback);
 }
 
@@ -193,8 +193,8 @@
   NumericDiffOptions numeric_diff_options;
   numeric_diff_options.relative_step_size = relative_step_size;
 
-  ProblemImpl* gradient_checking_problem_impl = new ProblemImpl(
-      gradient_checking_problem_options);
+  ProblemImpl* gradient_checking_problem_impl =
+      new ProblemImpl(gradient_checking_problem_options);
 
   Program* program = problem_impl->mutable_program();
 
@@ -213,7 +213,7 @@
           parameter_block->mutable_user_state());
     }
 
-    for (int i = 0; i <  parameter_block->Size(); ++i) {
+    for (int i = 0; i < parameter_block->Size(); ++i) {
       gradient_checking_problem_impl->SetParameterUpperBound(
           parameter_block->mutable_user_state(),
           i,
@@ -235,8 +235,8 @@
     // Build a human readable string which identifies the
     // ResidualBlock. This is used by the GradientCheckingCostFunction
     // when logging debugging information.
-    string extra_info = StringPrintf(
-        "Residual block id %d; depends on parameters [", i);
+    string extra_info =
+        StringPrintf("Residual block id %d; depends on parameters [", i);
     vector<double*> parameter_blocks;
     vector<const LocalParameterization*> local_parameterizations;
     parameter_blocks.reserve(residual_block->NumParameterBlocks());
@@ -277,13 +277,11 @@
   // depend on this being the case, so we explicitly call
   // SetParameterBlockStatePtrsToUserStatePtrs to ensure that this is
   // the case.
-  gradient_checking_problem_impl
-      ->mutable_program()
+  gradient_checking_problem_impl->mutable_program()
       ->SetParameterBlockStatePtrsToUserStatePtrs();
 
   return gradient_checking_problem_impl;
 }
 
-
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/gradient_checking_cost_function.h b/internal/ceres/gradient_checking_cost_function.h
index b2cd26e..ea6e9b3 100644
--- a/internal/ceres/gradient_checking_cost_function.h
+++ b/internal/ceres/gradient_checking_cost_function.h
@@ -36,6 +36,7 @@
 #include <string>
 
 #include "ceres/cost_function.h"
+#include "ceres/internal/port.h"
 #include "ceres/iteration_callback.h"
 #include "ceres/local_parameterization.h"
 
@@ -46,13 +47,14 @@
 
 // Callback that collects information about gradient checking errors, and
 // will abort the solve as soon as an error occurs.
-class GradientCheckingIterationCallback : public IterationCallback {
+class CERES_EXPORT_INTERNAL GradientCheckingIterationCallback
+    : public IterationCallback {
  public:
   GradientCheckingIterationCallback();
 
   // Will return SOLVER_CONTINUE until a gradient error has been detected,
   // then return SOLVER_ABORT.
-  virtual CallbackReturnType operator()(const IterationSummary& summary);
+  CallbackReturnType operator()(const IterationSummary& summary) final;
 
   // Notify this that a gradient error has occurred (thread safe).
   void SetGradientErrorDetected(std::string& error_log);
@@ -60,6 +62,7 @@
   // Retrieve error status (not thread safe).
   bool gradient_error_detected() const { return gradient_error_detected_; }
   const std::string& error_log() const { return error_log_; }
+
  private:
   bool gradient_error_detected_;
   std::string error_log_;
@@ -70,7 +73,7 @@
 // with finite differences. This API is only intended for unit tests that intend
 // to  check the functionality of the GradientCheckingCostFunction
 // implementation directly.
-CostFunction* CreateGradientCheckingCostFunction(
+CERES_EXPORT_INTERNAL CostFunction* CreateGradientCheckingCostFunction(
     const CostFunction* cost_function,
     const std::vector<const LocalParameterization*>* local_parameterizations,
     double relative_step_size,
@@ -99,7 +102,7 @@
 // jacobians obtained by numerically differentiating them. See the
 // documentation of 'numeric_derivative_relative_step_size' in solver.h for a
 // better explanation.
-ProblemImpl* CreateGradientCheckingProblemImpl(
+CERES_EXPORT_INTERNAL ProblemImpl* CreateGradientCheckingProblemImpl(
     ProblemImpl* problem_impl,
     double relative_step_size,
     double relative_precision,
diff --git a/internal/ceres/gradient_checking_cost_function_test.cc b/internal/ceres/gradient_checking_cost_function_test.cc
index f08bcd0..9ca51f8 100644
--- a/internal/ceres/gradient_checking_cost_function_test.cc
+++ b/internal/ceres/gradient_checking_cost_function_test.cc
@@ -53,10 +53,10 @@
 namespace internal {
 
 using std::vector;
+using testing::_;
 using testing::AllOf;
 using testing::AnyNumber;
 using testing::HasSubstr;
-using testing::_;
 
 // Pick a (non-quadratic) function whose derivative are easy:
 //
@@ -65,12 +65,12 @@
 //
 // where 'a' is a vector of the same size as 'x'. In the block
 // version, they are both block vectors, of course.
-template<int bad_block = 1, int bad_variable = 2>
+template <int bad_block = 1, int bad_variable = 2>
 class TestTerm : public CostFunction {
  public:
   // The constructor of this function needs to know the number
   // of blocks desired, and the size of each block.
-  TestTerm(int arity, int const *dim) : arity_(arity) {
+  TestTerm(int arity, int const* dim) : arity_(arity) {
     // Make 'arity' random vectors.
     a_.resize(arity_);
     for (int j = 0; j < arity_; ++j) {
@@ -107,7 +107,7 @@
         if (jacobians[j]) {
           for (int u = 0; u < parameter_block_sizes()[j]; ++u) {
             // See comments before class.
-            jacobians[j][u] = - f * a_[j][u];
+            jacobians[j][u] = -f * a_[j][u];
 
             if (bad_block == j && bad_variable == u) {
               // Whoopsiedoopsie! Deliberately introduce a faulty jacobian entry
@@ -135,7 +135,7 @@
 
   // Test with 3 blocks of size 2, 3 and 4.
   int const arity = 3;
-  int const dim[arity] = { 2, 3, 4 };
+  int const dim[arity] = {2, 3, 4};
 
   // Make a random set of blocks.
   vector<double*> parameters(arity);
@@ -164,17 +164,16 @@
   TestTerm<-1, -1> term(arity, dim);
   GradientCheckingIterationCallback callback;
   std::unique_ptr<CostFunction> gradient_checking_cost_function(
-      CreateGradientCheckingCostFunction(&term, NULL,
+      CreateGradientCheckingCostFunction(&term,
+                                         NULL,
                                          kRelativeStepSize,
                                          kRelativePrecision,
-                                         "Ignored.", &callback));
-  term.Evaluate(&parameters[0],
-                &original_residual,
-                &original_jacobians[0]);
+                                         "Ignored.",
+                                         &callback));
+  term.Evaluate(&parameters[0], &original_residual, &original_jacobians[0]);
 
-  gradient_checking_cost_function->Evaluate(&parameters[0],
-                                            &residual,
-                                            &jacobians[0]);
+  gradient_checking_cost_function->Evaluate(
+      &parameters[0], &residual, &jacobians[0]);
   EXPECT_EQ(original_residual, residual);
 
   for (int j = 0; j < arity; j++) {
@@ -193,7 +192,7 @@
 
   // Test with 3 blocks of size 2, 3 and 4.
   int const arity = 3;
-  int const dim[arity] = { 2, 3, 4 };
+  int const dim[arity] = {2, 3, 4};
 
   // Make a random set of blocks.
   vector<double*> parameters(arity);
@@ -221,17 +220,18 @@
     TestTerm<1, 2> term(arity, dim);
     GradientCheckingIterationCallback callback;
     std::unique_ptr<CostFunction> gradient_checking_cost_function(
-        CreateGradientCheckingCostFunction(&term, NULL,
+        CreateGradientCheckingCostFunction(&term,
+                                           NULL,
                                            kRelativeStepSize,
                                            kRelativePrecision,
-                                           "Fuzzy banana", &callback));
-    EXPECT_TRUE(
-        gradient_checking_cost_function->Evaluate(&parameters[0], &residual,
-                                                  &jacobians[0]));
+                                           "Fuzzy banana",
+                                           &callback));
+    EXPECT_TRUE(gradient_checking_cost_function->Evaluate(
+        &parameters[0], &residual, &jacobians[0]));
     EXPECT_TRUE(callback.gradient_error_detected());
     EXPECT_TRUE(callback.error_log().find("Fuzzy banana") != std::string::npos);
-    EXPECT_TRUE(callback.error_log().find("(1,0,2) Relative error worse than")
-                != std::string::npos);
+    EXPECT_TRUE(callback.error_log().find(
+                    "(1,0,2) Relative error worse than") != std::string::npos);
   }
 
   // The gradient is correct, so no errors are reported.
@@ -240,13 +240,14 @@
     TestTerm<-1, -1> term(arity, dim);
     GradientCheckingIterationCallback callback;
     std::unique_ptr<CostFunction> gradient_checking_cost_function(
-        CreateGradientCheckingCostFunction(&term, NULL,
+        CreateGradientCheckingCostFunction(&term,
+                                           NULL,
                                            kRelativeStepSize,
                                            kRelativePrecision,
-                                           "Fuzzy banana", &callback));
-    EXPECT_TRUE(
-        gradient_checking_cost_function->Evaluate(&parameters[0], &residual,
-                                                  &jacobians[0]));
+                                           "Fuzzy banana",
+                                           &callback));
+    EXPECT_TRUE(gradient_checking_cost_function->Evaluate(
+        &parameters[0], &residual, &jacobians[0]));
     EXPECT_FALSE(callback.gradient_error_detected());
   }
 
@@ -268,9 +269,9 @@
   }
   virtual ~UnaryCostFunction() {}
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     for (int i = 0; i < num_residuals(); ++i) {
       residuals[i] = 1;
     }
@@ -279,7 +280,7 @@
 };
 
 // Trivial cost function that accepts two arguments.
-class BinaryCostFunction: public CostFunction {
+class BinaryCostFunction : public CostFunction {
  public:
   BinaryCostFunction(int num_residuals,
                      int32_t parameter_block1_size,
@@ -289,9 +290,9 @@
     mutable_parameter_block_sizes()->push_back(parameter_block2_size);
   }
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     for (int i = 0; i < num_residuals(); ++i) {
       residuals[i] = 2;
     }
@@ -300,7 +301,7 @@
 };
 
 // Trivial cost function that accepts three arguments.
-class TernaryCostFunction: public CostFunction {
+class TernaryCostFunction : public CostFunction {
  public:
   TernaryCostFunction(int num_residuals,
                       int32_t parameter_block1_size,
@@ -312,9 +313,9 @@
     mutable_parameter_block_sizes()->push_back(parameter_block3_size);
   }
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     for (int i = 0; i < num_residuals(); ++i) {
       residuals[i] = 3;
     }
@@ -324,8 +325,8 @@
 
 // Verify that the two ParameterBlocks are formed from the same user
 // array and have the same LocalParameterization object.
-void ParameterBlocksAreEquivalent(const ParameterBlock*  left,
-                                  const ParameterBlock* right) {
+static void ParameterBlocksAreEquivalent(const ParameterBlock* left,
+                                         const ParameterBlock* right) {
   CHECK(left != nullptr);
   CHECK(right != nullptr);
   EXPECT_EQ(left->user_state(), right->user_state());
@@ -349,8 +350,10 @@
   problem_impl.SetParameterBlockConstant(y);
   problem_impl.AddParameterBlock(z, 5);
   problem_impl.AddParameterBlock(w, 4, new QuaternionParameterization);
-  problem_impl.AddResidualBlock(new UnaryCostFunction(2, 3), NULL, x);
-  problem_impl.AddResidualBlock(new BinaryCostFunction(6, 5, 4) ,
+  // clang-format off
+  problem_impl.AddResidualBlock(new UnaryCostFunction(2, 3),
+                                NULL, x);
+  problem_impl.AddResidualBlock(new BinaryCostFunction(6, 5, 4),
                                 NULL, z, y);
   problem_impl.AddResidualBlock(new BinaryCostFunction(3, 3, 5),
                                 new TrivialLoss, x, z);
@@ -358,6 +361,7 @@
                                 NULL, z, x);
   problem_impl.AddResidualBlock(new TernaryCostFunction(1, 5, 3, 4),
                                 NULL, z, x, y);
+  // clang-format on
 
   GradientCheckingIterationCallback callback;
   std::unique_ptr<ProblemImpl> gradient_checking_problem_impl(
@@ -392,8 +396,7 @@
 
   for (int i = 0; i < program.residual_blocks().size(); ++i) {
     // Compare the sizes of the two ResidualBlocks.
-    const ResidualBlock* original_residual_block =
-        program.residual_blocks()[i];
+    const ResidualBlock* original_residual_block = program.residual_blocks()[i];
     const ResidualBlock* new_residual_block =
         gradient_checking_program.residual_blocks()[i];
     EXPECT_EQ(original_residual_block->NumParameterBlocks(),
@@ -412,15 +415,14 @@
   }
 }
 
-
 TEST(GradientCheckingProblemImpl, ConstrainedProblemBoundsArePropagated) {
   // Parameter blocks with arbitrarily chosen initial values.
   double x[] = {1.0, 2.0, 3.0};
   ProblemImpl problem_impl;
   problem_impl.AddParameterBlock(x, 3);
   problem_impl.AddResidualBlock(new UnaryCostFunction(2, 3), NULL, x);
-  problem_impl.SetParameterLowerBound(x,0,0.9);
-  problem_impl.SetParameterUpperBound(x,1,2.5);
+  problem_impl.SetParameterLowerBound(x, 0, 0.9);
+  problem_impl.SetParameterUpperBound(x, 1, 2.5);
 
   GradientCheckingIterationCallback callback;
   std::unique_ptr<ProblemImpl> gradient_checking_problem_impl(
diff --git a/internal/ceres/gradient_problem.cc b/internal/ceres/gradient_problem.cc
index 4ebd3e6..ba33fbc 100644
--- a/internal/ceres/gradient_problem.cc
+++ b/internal/ceres/gradient_problem.cc
@@ -29,6 +29,7 @@
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
 #include "ceres/gradient_problem.h"
+
 #include "ceres/local_parameterization.h"
 #include "glog/logging.h"
 
@@ -38,14 +39,13 @@
     : function_(function),
       parameterization_(
           new IdentityParameterization(function_->NumParameters())),
-      scratch_(new double[function_->NumParameters()]) {
-}
+      scratch_(new double[function_->NumParameters()]) {}
 
 GradientProblem::GradientProblem(FirstOrderFunction* function,
                                  LocalParameterization* parameterization)
-      : function_(function),
-        parameterization_(parameterization),
-        scratch_(new double[function_->NumParameters()]) {
+    : function_(function),
+      parameterization_(parameterization),
+      scratch_(new double[function_->NumParameters()]) {
   CHECK_EQ(function_->NumParameters(), parameterization_->GlobalSize());
 }
 
@@ -57,7 +57,6 @@
   return parameterization_->LocalSize();
 }
 
-
 bool GradientProblem::Evaluate(const double* parameters,
                                double* cost,
                                double* gradient) const {
@@ -66,10 +65,8 @@
   }
 
   return (function_->Evaluate(parameters, cost, scratch_.get()) &&
-          parameterization_->MultiplyByJacobian(parameters,
-                                                1,
-                                                scratch_.get(),
-                                                gradient));
+          parameterization_->MultiplyByJacobian(
+              parameters, 1, scratch_.get(), gradient));
 }
 
 bool GradientProblem::Plus(const double* x,
diff --git a/internal/ceres/gradient_problem_evaluator.h b/internal/ceres/gradient_problem_evaluator.h
index 5458631..d224dbe 100644
--- a/internal/ceres/gradient_problem_evaluator.h
+++ b/internal/ceres/gradient_problem_evaluator.h
@@ -48,13 +48,13 @@
   explicit GradientProblemEvaluator(const GradientProblem& problem)
       : problem_(problem) {}
   virtual ~GradientProblemEvaluator() {}
-  virtual SparseMatrix* CreateJacobian() const { return NULL; }
-  virtual bool Evaluate(const EvaluateOptions& evaluate_options,
-                        const double* state,
-                        double* cost,
-                        double* residuals,
-                        double* gradient,
-                        SparseMatrix* jacobian) {
+  SparseMatrix* CreateJacobian() const final { return nullptr; }
+  bool Evaluate(const EvaluateOptions& evaluate_options,
+                const double* state,
+                double* cost,
+                double* residuals,
+                double* gradient,
+                SparseMatrix* jacobian) final {
     CHECK(jacobian == NULL);
     ScopedExecutionTimer total_timer("Evaluator::Total", &execution_summary_);
     // The reason we use Residual and Jacobian here even when we are
@@ -70,23 +70,21 @@
     return problem_.Evaluate(state, cost, gradient);
   }
 
-  virtual bool Plus(const double* state,
-                    const double* delta,
-                    double* state_plus_delta) const {
+  bool Plus(const double* state,
+            const double* delta,
+            double* state_plus_delta) const final {
     return problem_.Plus(state, delta, state_plus_delta);
   }
 
-  virtual int NumParameters() const {
-    return problem_.NumParameters();
-  }
+  int NumParameters() const final { return problem_.NumParameters(); }
 
-  virtual int NumEffectiveParameters()  const {
+  int NumEffectiveParameters() const final {
     return problem_.NumLocalParameters();
   }
 
-  virtual int NumResiduals() const { return 1; }
+  int NumResiduals() const final { return 1; }
 
-  virtual std::map<std::string, internal::CallStatistics> Statistics() const {
+  std::map<std::string, internal::CallStatistics> Statistics() const final {
     return execution_summary_.statistics();
   }
 
diff --git a/internal/ceres/gradient_problem_solver.cc b/internal/ceres/gradient_problem_solver.cc
index 1639e30..b72fad9 100644
--- a/internal/ceres/gradient_problem_solver.cc
+++ b/internal/ceres/gradient_problem_solver.cc
@@ -31,6 +31,7 @@
 #include "ceres/gradient_problem_solver.h"
 
 #include <memory>
+
 #include "ceres/callbacks.h"
 #include "ceres/gradient_problem.h"
 #include "ceres/gradient_problem_evaluator.h"
@@ -45,8 +46,8 @@
 #include "ceres/wall_time.h"
 
 namespace ceres {
-using internal::StringPrintf;
 using internal::StringAppendF;
+using internal::StringPrintf;
 using std::string;
 
 namespace {
@@ -83,7 +84,6 @@
 #undef COPY_OPTION
 }
 
-
 }  // namespace
 
 bool GradientProblemSolver::Options::IsValid(std::string* error) const {
@@ -92,8 +92,7 @@
   return solver_options.IsValid(error);
 }
 
-GradientProblemSolver::~GradientProblemSolver() {
-}
+GradientProblemSolver::~GradientProblemSolver() {}
 
 void GradientProblemSolver::Solve(const GradientProblemSolver::Options& options,
                                   const GradientProblem& problem,
@@ -111,6 +110,7 @@
 
   CHECK(summary != nullptr);
   *summary = Summary();
+  // clang-format off
   summary->num_parameters                    = problem.NumParameters();
   summary->num_local_parameters              = problem.NumLocalParameters();
   summary->line_search_direction_type        = options.line_search_direction_type;         //  NOLINT
@@ -118,6 +118,7 @@
   summary->line_search_type                  = options.line_search_type;
   summary->max_lbfgs_rank                    = options.max_lbfgs_rank;
   summary->nonlinear_conjugate_gradient_type = options.nonlinear_conjugate_gradient_type;  //  NOLINT
+  // clang-format on
 
   // Check validity
   if (!options.IsValid(&summary->message)) {
@@ -163,11 +164,13 @@
 
   minimizer->Minimize(minimizer_options, solution.data(), &solver_summary);
 
+  // clang-format off
   summary->termination_type = solver_summary.termination_type;
   summary->message          = solver_summary.message;
   summary->initial_cost     = solver_summary.initial_cost;
   summary->final_cost       = solver_summary.final_cost;
   summary->iterations       = solver_summary.iterations;
+  // clang-format on
   summary->line_search_polynomial_minimization_time_in_seconds =
       solver_summary.line_search_polynomial_minimization_time_in_seconds;
 
@@ -200,15 +203,16 @@
 }
 
 string GradientProblemSolver::Summary::BriefReport() const {
-  return StringPrintf("Ceres GradientProblemSolver Report: "
-                      "Iterations: %d, "
-                      "Initial cost: %e, "
-                      "Final cost: %e, "
-                      "Termination: %s",
-                      static_cast<int>(iterations.size()),
-                      initial_cost,
-                      final_cost,
-                      TerminationTypeToString(termination_type));
+  return StringPrintf(
+      "Ceres GradientProblemSolver Report: "
+      "Iterations: %d, "
+      "Initial cost: %e, "
+      "Final cost: %e, "
+      "Termination: %s",
+      static_cast<int>(iterations.size()),
+      initial_cost,
+      final_cost,
+      TerminationTypeToString(termination_type));
 }
 
 string GradientProblemSolver::Summary::FullReport() const {
@@ -218,60 +222,63 @@
 
   StringAppendF(&report, "Parameters          % 25d\n", num_parameters);
   if (num_local_parameters != num_parameters) {
-    StringAppendF(&report, "Local parameters    % 25d\n",
-                  num_local_parameters);
+    StringAppendF(&report, "Local parameters    % 25d\n", num_local_parameters);
   }
 
   string line_search_direction_string;
   if (line_search_direction_type == LBFGS) {
     line_search_direction_string = StringPrintf("LBFGS (%d)", max_lbfgs_rank);
   } else if (line_search_direction_type == NONLINEAR_CONJUGATE_GRADIENT) {
-    line_search_direction_string =
-        NonlinearConjugateGradientTypeToString(
-            nonlinear_conjugate_gradient_type);
+    line_search_direction_string = NonlinearConjugateGradientTypeToString(
+        nonlinear_conjugate_gradient_type);
   } else {
     line_search_direction_string =
         LineSearchDirectionTypeToString(line_search_direction_type);
   }
 
-  StringAppendF(&report, "Line search direction     %19s\n",
+  StringAppendF(&report,
+                "Line search direction     %19s\n",
                 line_search_direction_string.c_str());
 
-  const string line_search_type_string =
-      StringPrintf("%s %s",
-                   LineSearchInterpolationTypeToString(
-                       line_search_interpolation_type),
-                   LineSearchTypeToString(line_search_type));
-  StringAppendF(&report, "Line search type          %19s\n",
+  const string line_search_type_string = StringPrintf(
+      "%s %s",
+      LineSearchInterpolationTypeToString(line_search_interpolation_type),
+      LineSearchTypeToString(line_search_type));
+  StringAppendF(&report,
+                "Line search type          %19s\n",
                 line_search_type_string.c_str());
   StringAppendF(&report, "\n");
 
   StringAppendF(&report, "\nCost:\n");
   StringAppendF(&report, "Initial        % 30e\n", initial_cost);
-  if (termination_type != FAILURE &&
-      termination_type != USER_FAILURE) {
+  if (termination_type != FAILURE && termination_type != USER_FAILURE) {
     StringAppendF(&report, "Final          % 30e\n", final_cost);
-    StringAppendF(&report, "Change         % 30e\n",
-                  initial_cost - final_cost);
+    StringAppendF(&report, "Change         % 30e\n", initial_cost - final_cost);
   }
 
-  StringAppendF(&report, "\nMinimizer iterations         % 16d\n",
+  StringAppendF(&report,
+                "\nMinimizer iterations         % 16d\n",
                 static_cast<int>(iterations.size()));
 
   StringAppendF(&report, "\nTime (in seconds):\n");
-  StringAppendF(&report, "\n  Cost evaluation     %23.6f (%d)\n",
+  StringAppendF(&report,
+                "\n  Cost evaluation     %23.6f (%d)\n",
                 cost_evaluation_time_in_seconds,
                 num_cost_evaluations);
-  StringAppendF(&report, "  Gradient & cost evaluation %16.6f (%d)\n",
+  StringAppendF(&report,
+                "  Gradient & cost evaluation %16.6f (%d)\n",
                 gradient_evaluation_time_in_seconds,
                 num_gradient_evaluations);
-  StringAppendF(&report, "  Polynomial minimization   %17.6f\n",
+  StringAppendF(&report,
+                "  Polynomial minimization   %17.6f\n",
                 line_search_polynomial_minimization_time_in_seconds);
-  StringAppendF(&report, "Total               %25.6f\n\n",
-                total_time_in_seconds);
+  StringAppendF(
+      &report, "Total               %25.6f\n\n", total_time_in_seconds);
 
-  StringAppendF(&report, "Termination:        %25s (%s)\n",
-                TerminationTypeToString(termination_type), message.c_str());
+  StringAppendF(&report,
+                "Termination:        %25s (%s)\n",
+                TerminationTypeToString(termination_type),
+                message.c_str());
   return report;
 }
 
diff --git a/internal/ceres/gradient_problem_solver_test.cc b/internal/ceres/gradient_problem_solver_test.cc
index 20574de..f01d206 100644
--- a/internal/ceres/gradient_problem_solver_test.cc
+++ b/internal/ceres/gradient_problem_solver_test.cc
@@ -28,9 +28,9 @@
 //
 // Author: strandmark@google.com (Petter Strandmark)
 
-#include "ceres/gradient_problem.h"
 #include "ceres/gradient_problem_solver.h"
 
+#include "ceres/gradient_problem.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -41,9 +41,9 @@
  public:
   virtual ~Rosenbrock() {}
 
-  virtual bool Evaluate(const double* parameters,
-                        double* cost,
-                        double* gradient) const {
+  bool Evaluate(const double* parameters,
+                double* cost,
+                double* gradient) const final {
     const double x = parameters[0];
     const double y = parameters[1];
 
@@ -55,7 +55,7 @@
     return true;
   }
 
-  virtual int NumParameters() const { return 2; }
+  int NumParameters() const final { return 2; }
 };
 
 TEST(GradientProblemSolver, SolvesRosenbrockWithDefaultOptions) {
@@ -74,9 +74,9 @@
 
 class QuadraticFunction : public ceres::FirstOrderFunction {
   virtual ~QuadraticFunction() {}
-  virtual bool Evaluate(const double* parameters,
-                        double* cost,
-                        double* gradient) const {
+  bool Evaluate(const double* parameters,
+                double* cost,
+                double* gradient) const final {
     const double x = parameters[0];
     *cost = 0.5 * (5.0 - x) * (5.0 - x);
     if (gradient != NULL) {
@@ -85,22 +85,21 @@
 
     return true;
   }
-  virtual int NumParameters() const { return 1; }
+  int NumParameters() const final { return 1; }
 };
 
 struct RememberingCallback : public IterationCallback {
-  explicit RememberingCallback(double *x) : calls(0), x(x) {}
+  explicit RememberingCallback(double* x) : calls(0), x(x) {}
   virtual ~RememberingCallback() {}
-  virtual CallbackReturnType operator()(const IterationSummary& summary) {
+  CallbackReturnType operator()(const IterationSummary& summary) final {
     x_values.push_back(*x);
     return SOLVER_CONTINUE;
   }
   int calls;
-  double *x;
+  double* x;
   std::vector<double> x_values;
 };
 
-
 TEST(Solver, UpdateStateEveryIterationOption) {
   double x = 50.0;
   const double original_x = x;
diff --git a/internal/ceres/gradient_problem_test.cc b/internal/ceres/gradient_problem_test.cc
index b352577..8934138 100644
--- a/internal/ceres/gradient_problem_test.cc
+++ b/internal/ceres/gradient_problem_test.cc
@@ -46,9 +46,9 @@
     }
   }
 
-  virtual bool Evaluate(const double* parameters,
-                        double* cost,
-                        double* gradient) const {
+  bool Evaluate(const double* parameters,
+                double* cost,
+                double* gradient) const final {
     const double x = parameters[0];
     cost[0] = x * x;
     if (gradient != NULL) {
@@ -57,7 +57,7 @@
     return true;
   }
 
-  virtual int NumParameters() const { return 1; }
+  int NumParameters() const final { return 1; }
 
  private:
   bool* flag_to_set_on_destruction_;
@@ -65,9 +65,7 @@
 
 TEST(GradientProblem, TakesOwnershipOfFirstOrderFunction) {
   bool is_destructed = false;
-  {
-    ceres::GradientProblem problem(new QuadraticTestFunction(&is_destructed));
-  }
+  { ceres::GradientProblem problem(new QuadraticTestFunction(&is_destructed)); }
   EXPECT_TRUE(is_destructed);
 }
 
diff --git a/internal/ceres/graph.h b/internal/ceres/graph.h
index 4e1fd81..9b26158 100644
--- a/internal/ceres/graph.h
+++ b/internal/ceres/graph.h
@@ -32,9 +32,10 @@
 #define CERES_INTERNAL_GRAPH_H_
 
 #include <limits>
-#include <unordered_set>
 #include <unordered_map>
+#include <unordered_set>
 #include <utility>
+
 #include "ceres/map_util.h"
 #include "ceres/pair_hash.h"
 #include "ceres/types.h"
@@ -93,9 +94,7 @@
     return FindOrDie(edges_, vertex);
   }
 
-  const std::unordered_set<Vertex>& vertices() const {
-    return vertices_;
-  }
+  const std::unordered_set<Vertex>& vertices() const { return vertices_; }
 
  private:
   std::unordered_set<Vertex> vertices_;
@@ -121,9 +120,7 @@
 
   // Uses weight = 1.0. If vertex already exists, its weight is set to
   // 1.0.
-  void AddVertex(const Vertex& vertex) {
-    AddVertex(vertex, 1.0);
-  }
+  void AddVertex(const Vertex& vertex) { AddVertex(vertex, 1.0); }
 
   bool RemoveVertex(const Vertex& vertex) {
     if (vertices_.find(vertex) == vertices_.end()) {
@@ -184,11 +181,11 @@
   // the edge weight is zero.
   double EdgeWeight(const Vertex& vertex1, const Vertex& vertex2) const {
     if (vertex1 < vertex2) {
-      return FindWithDefault(edge_weights_,
-                             std::make_pair(vertex1, vertex2), 0.0);
+      return FindWithDefault(
+          edge_weights_, std::make_pair(vertex1, vertex2), 0.0);
     } else {
-      return FindWithDefault(edge_weights_,
-                             std::make_pair(vertex2, vertex1), 0.0);
+      return FindWithDefault(
+          edge_weights_, std::make_pair(vertex2, vertex1), 0.0);
     }
   }
 
@@ -198,9 +195,7 @@
     return FindOrDie(edges_, vertex);
   }
 
-  const std::unordered_set<Vertex>& vertices() const {
-    return vertices_;
-  }
+  const std::unordered_set<Vertex>& vertices() const { return vertices_; }
 
   static double InvalidWeight() {
     return std::numeric_limits<double>::quiet_NaN();
diff --git a/internal/ceres/graph_algorithms.h b/internal/ceres/graph_algorithms.h
index b062931..7d63b33 100644
--- a/internal/ceres/graph_algorithms.h
+++ b/internal/ceres/graph_algorithms.h
@@ -36,8 +36,9 @@
 #include <algorithm>
 #include <unordered_map>
 #include <unordered_set>
-#include <vector>
 #include <utility>
+#include <vector>
+
 #include "ceres/graph.h"
 #include "ceres/wall_time.h"
 #include "glog/logging.h"
@@ -50,8 +51,7 @@
 template <typename Vertex>
 class VertexTotalOrdering {
  public:
-  explicit VertexTotalOrdering(const Graph<Vertex>& graph)
-      : graph_(graph) {}
+  explicit VertexTotalOrdering(const Graph<Vertex>& graph) : graph_(graph) {}
 
   bool operator()(const Vertex& lhs, const Vertex& rhs) const {
     if (graph_.Neighbors(lhs).size() == graph_.Neighbors(rhs).size()) {
@@ -67,8 +67,7 @@
 template <typename Vertex>
 class VertexDegreeLessThan {
  public:
-  explicit VertexDegreeLessThan(const Graph<Vertex>& graph)
-      : graph_(graph) {}
+  explicit VertexDegreeLessThan(const Graph<Vertex>& graph) : graph_(graph) {}
 
   bool operator()(const Vertex& lhs, const Vertex& rhs) const {
     return graph_.Neighbors(lhs).size() < graph_.Neighbors(rhs).size();
@@ -177,8 +176,9 @@
 
   std::vector<Vertex> vertex_queue(*ordering);
 
-  std::stable_sort(vertex_queue.begin(), vertex_queue.end(),
-                  VertexDegreeLessThan<Vertex>(graph));
+  std::stable_sort(vertex_queue.begin(),
+                   vertex_queue.end(),
+                   VertexDegreeLessThan<Vertex>(graph));
 
   // Mark all vertices white.
   std::unordered_map<Vertex, char> vertex_color;
@@ -257,8 +257,8 @@
 // spanning forest, or a collection of linear paths that span the
 // graph G.
 template <typename Vertex>
-WeightedGraph<Vertex>*
-Degree2MaximumSpanningForest(const WeightedGraph<Vertex>& graph) {
+WeightedGraph<Vertex>* Degree2MaximumSpanningForest(
+    const WeightedGraph<Vertex>& graph) {
   // Array of edges sorted in decreasing order of their weights.
   std::vector<std::pair<double, std::pair<Vertex, Vertex>>> weighted_edges;
   WeightedGraph<Vertex>* forest = new WeightedGraph<Vertex>();
@@ -294,7 +294,7 @@
 
   // Greedily add edges to the spanning tree/forest as long as they do
   // not violate the degree/cycle constraint.
-  for (int i =0; i < weighted_edges.size(); ++i) {
+  for (int i = 0; i < weighted_edges.size(); ++i) {
     const std::pair<Vertex, Vertex>& edge = weighted_edges[i].second;
     const Vertex vertex1 = edge.first;
     const Vertex vertex2 = edge.second;
diff --git a/internal/ceres/graph_algorithms_test.cc b/internal/ceres/graph_algorithms_test.cc
index 2aef327..d5dd02e 100644
--- a/internal/ceres/graph_algorithms_test.cc
+++ b/internal/ceres/graph_algorithms_test.cc
@@ -111,8 +111,8 @@
   graph.AddEdge(0, 1, 0.5);
   graph.AddEdge(1, 0, 0.5);
 
-  std::unique_ptr<WeightedGraph<int> > forest(
-					      Degree2MaximumSpanningForest(graph));
+  std::unique_ptr<WeightedGraph<int>> forest(
+      Degree2MaximumSpanningForest(graph));
 
   const std::unordered_set<int>& vertices = forest->vertices();
   EXPECT_EQ(vertices.size(), 2);
@@ -135,7 +135,8 @@
   graph.AddEdge(0, 3, 3.0);
   graph.AddEdge(0, 4, 4.0);
 
-  std::unique_ptr<WeightedGraph<int> > forest(Degree2MaximumSpanningForest(graph));
+  std::unique_ptr<WeightedGraph<int>> forest(
+      Degree2MaximumSpanningForest(graph));
   const std::unordered_set<int>& vertices = forest->vertices();
   EXPECT_EQ(vertices.size(), 5);
 
@@ -200,7 +201,6 @@
   }
 }
 
-
 TEST(StableIndependentSet, BreakTies) {
   Graph<int> graph;
   graph.AddVertex(0);
diff --git a/internal/ceres/graph_test.cc b/internal/ceres/graph_test.cc
index 8f05475..2154a06 100644
--- a/internal/ceres/graph_test.cc
+++ b/internal/ceres/graph_test.cc
@@ -31,6 +31,7 @@
 #include "ceres/graph.h"
 
 #include <unordered_set>
+
 #include "gtest/gtest.h"
 
 namespace ceres {
diff --git a/internal/ceres/gtest/.clang-format b/internal/ceres/gtest/.clang-format
new file mode 100644
index 0000000..9d15924
--- /dev/null
+++ b/internal/ceres/gtest/.clang-format
@@ -0,0 +1,2 @@
+DisableFormat: true
+SortIncludes: false
diff --git a/internal/ceres/gtest/gtest.h b/internal/ceres/gtest/gtest.h
index aea1f51..a8344fe 100644
--- a/internal/ceres/gtest/gtest.h
+++ b/internal/ceres/gtest/gtest.h
@@ -26,10 +26,9 @@
 // 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: wan@google.com (Zhanyong Wan)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
 //
 // This header file defines the public API for Google Test.  It should be
 // included by any test program that uses Google Test.
@@ -48,10 +47,13 @@
 // registration from Barthelemy Dagenais' (barthelemy@prologique.com)
 // easyUnit framework.
 
+// GOOGLETEST_CM0001 DO NOT DELETE
+
 #ifndef GTEST_INCLUDE_GTEST_GTEST_H_
 #define GTEST_INCLUDE_GTEST_GTEST_H_
 
 #include <limits>
+#include <memory>
 #include <ostream>
 #include <vector>
 
@@ -84,13 +86,13 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
-// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
 //
 // This header file declares functions and macros used internally by
 // Google Test.  They are subject to change without notice.
 
+// GOOGLETEST_CM0001 DO NOT DELETE
+
 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
 
@@ -123,8 +125,6 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
-// Authors: wan@google.com (Zhanyong Wan)
-//
 // Low-level types and utilities for porting Google Test to various
 // platforms.  All macros ending with _ and symbols defined in an
 // internal namespace are subject to change without notice.  Code
@@ -136,6 +136,8 @@
 // files are expected to #include this.  Therefore, it cannot #include
 // any other Google Test header.
 
+// GOOGLETEST_CM0001 DO NOT DELETE
+
 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
 
@@ -169,11 +171,9 @@
 //   GTEST_HAS_EXCEPTIONS     - Define it to 1/0 to indicate that exceptions
 //                              are enabled.
 //   GTEST_HAS_GLOBAL_STRING  - Define it to 1/0 to indicate that ::string
-//                              is/isn't available (some systems define
-//                              ::string, which is different to std::string).
-//   GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string
-//                              is/isn't available (some systems define
-//                              ::wstring, which is different to std::wstring).
+//                              is/isn't available
+//   GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::wstring
+//                              is/isn't available
 //   GTEST_HAS_POSIX_RE       - Define it to 1/0 to indicate that POSIX regular
 //                              expressions are/aren't available.
 //   GTEST_HAS_PTHREAD        - Define it to 1/0 to indicate that <pthread.h>
@@ -183,8 +183,6 @@
 //   GTEST_HAS_STD_WSTRING    - Define it to 1/0 to indicate that
 //                              std::wstring does/doesn't work (Google Test can
 //                              be used where std::wstring is unavailable).
-//   GTEST_HAS_TR1_TUPLE      - Define it to 1/0 to indicate tr1::tuple
-//                              is/isn't available.
 //   GTEST_HAS_SEH            - Define it to 1/0 to indicate whether the
 //                              compiler supports Microsoft's "Structured
 //                              Exception Handling".
@@ -192,12 +190,6 @@
 //                            - Define it to 1/0 to indicate whether the
 //                              platform supports I/O stream redirection using
 //                              dup() and dup2().
-//   GTEST_USE_OWN_TR1_TUPLE  - Define it to 1/0 to indicate whether Google
-//                              Test's own tr1 tuple implementation should be
-//                              used.  Unused when the user sets
-//                              GTEST_HAS_TR1_TUPLE to 0.
-//   GTEST_LANG_CXX11         - Define it to 1/0 to indicate that Google Test
-//                              is building in C++11/C++98 mode.
 //   GTEST_LINKED_AS_SHARED_LIBRARY
 //                            - Define to 1 when compiling tests that use
 //                              Google Test as a shared library (known as
@@ -205,6 +197,12 @@
 //   GTEST_CREATE_SHARED_LIBRARY
 //                            - Define to 1 when compiling Google Test itself
 //                              as a shared library.
+//   GTEST_DEFAULT_DEATH_TEST_STYLE
+//                            - The default value of --gtest_death_test_style.
+//                              The legacy default has been "fast" in the open
+//                              source version since 2008. The recommended value
+//                              is "threadsafe", and can be set in
+//                              custom/gtest-port.h.
 
 // Platform-indicating macros
 // --------------------------
@@ -217,17 +215,21 @@
 //
 //   GTEST_OS_AIX      - IBM AIX
 //   GTEST_OS_CYGWIN   - Cygwin
+//   GTEST_OS_DRAGONFLY - DragonFlyBSD
 //   GTEST_OS_FREEBSD  - FreeBSD
+//   GTEST_OS_FUCHSIA  - Fuchsia
+//   GTEST_OS_GNU_KFREEBSD - GNU/kFreeBSD
 //   GTEST_OS_HPUX     - HP-UX
 //   GTEST_OS_LINUX    - Linux
 //     GTEST_OS_LINUX_ANDROID - Google Android
 //   GTEST_OS_MAC      - Mac OS X
 //     GTEST_OS_IOS    - iOS
 //   GTEST_OS_NACL     - Google Native Client (NaCl)
+//   GTEST_OS_NETBSD   - NetBSD
 //   GTEST_OS_OPENBSD  - OpenBSD
+//   GTEST_OS_OS2      - OS/2
 //   GTEST_OS_QNX      - QNX
 //   GTEST_OS_SOLARIS  - Sun Solaris
-//   GTEST_OS_SYMBIAN  - Symbian
 //   GTEST_OS_WINDOWS  - Windows (Desktop, MinGW, or Mobile)
 //     GTEST_OS_WINDOWS_DESKTOP  - Windows Desktop
 //     GTEST_OS_WINDOWS_MINGW    - MinGW
@@ -262,19 +264,16 @@
 //   EXPECT_DEATH(DoSomethingDeadly());
 // #endif
 //
-//   GTEST_HAS_COMBINE      - the Combine() function (for value-parameterized
-//                            tests)
 //   GTEST_HAS_DEATH_TEST   - death tests
-//   GTEST_HAS_PARAM_TEST   - value-parameterized tests
 //   GTEST_HAS_TYPED_TEST   - typed tests
 //   GTEST_HAS_TYPED_TEST_P - type-parameterized tests
 //   GTEST_IS_THREADSAFE    - Google Test is thread-safe.
+//   GOOGLETEST_CM0007 DO NOT DELETE
 //   GTEST_USES_POSIX_RE    - enhanced POSIX regex is used. Do not confuse with
 //                            GTEST_HAS_POSIX_RE (see above) which users can
 //                            define themselves.
 //   GTEST_USES_SIMPLE_RE   - our own simple regex is used;
-//                            the above two are mutually exclusive.
-//   GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().
+//                            the above RE\b(s) are mutually exclusive.
 
 // Misc public macros
 // ------------------
@@ -300,28 +299,21 @@
 //   GTEST_INTENTIONAL_CONST_COND_POP_  - finish code section where MSVC C4127
 //                                        is suppressed.
 //
-// C++11 feature wrappers:
-//
-//   testing::internal::move  - portability wrapper for std::move.
-//
 // Synchronization:
 //   Mutex, MutexLock, ThreadLocal, GetThreadCount()
 //                            - synchronization primitives.
 //
 // Template meta programming:
-//   is_pointer     - as in TR1; needed on Symbian and IBM XL C/C++ only.
 //   IteratorTraits - partial implementation of std::iterator_traits, which
 //                    is not available in libCstd when compiled with Sun C++.
 //
-// Smart pointers:
-//   scoped_ptr     - as in TR2.
 //
 // Regular expressions:
 //   RE             - a simple regular expression class using the POSIX
-//                    Extended Regular Expression syntax on UNIX-like
-//                    platforms, or a reduced regular exception syntax on
-//                    other platforms, including Windows.
-//
+//                    Extended Regular Expression syntax on UNIX-like platforms
+//                    GOOGLETEST_CM0008 DO NOT DELETE
+//                    or a reduced regular exception syntax on other
+//                    platforms, including Windows.
 // Logging:
 //   GTEST_LOG_()   - logs messages at the specified severity level.
 //   LogToStderr()  - directs all log messages to stderr.
@@ -351,12 +343,20 @@
 //   BoolFromGTestEnv()   - parses a bool environment variable.
 //   Int32FromGTestEnv()  - parses an Int32 environment variable.
 //   StringFromGTestEnv() - parses a string environment variable.
+//
+// Deprecation warnings:
+//   GTEST_INTERNAL_DEPRECATED(message) - attribute marking a function as
+//                                        deprecated; calling a marked function
+//                                        should generate a compiler warning
 
 #include <ctype.h>   // for isspace, etc
 #include <stddef.h>  // for ptrdiff_t
-#include <stdlib.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
+#include <memory>
+#include <type_traits>
+
 #ifndef _WIN32_WCE
 # include <sys/types.h>
 # include <sys/stat.h>
@@ -367,10 +367,13 @@
 # include <TargetConditionals.h>
 #endif
 
+// Brings in the definition of HAS_GLOBAL_STRING.  This must be done
+// BEFORE we test HAS_GLOBAL_STRING.
+#include <string>     // NOLINT
 #include <algorithm>  // NOLINT
-#include <iostream>  // NOLINT
-#include <sstream>  // NOLINT
-#include <string>  // NOLINT
+#include <iostream>   // NOLINT
+#include <sstream>    // NOLINT
+#include <tuple>
 #include <utility>
 #include <vector>  // NOLINT
 
@@ -403,7 +406,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
 //
 // This header file defines the GTEST_OS_* macro.
 // It is separate from gtest-port.h so that custom/gtest-port.h can include it.
@@ -414,14 +417,13 @@
 // Determines the platform on which Google Test is compiled.
 #ifdef __CYGWIN__
 # define GTEST_OS_CYGWIN 1
-#elif defined __SYMBIAN32__
-# define GTEST_OS_SYMBIAN 1
+# elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)
+#  define GTEST_OS_WINDOWS_MINGW 1
+#  define GTEST_OS_WINDOWS 1
 #elif defined _WIN32
 # define GTEST_OS_WINDOWS 1
 # ifdef _WIN32_WCE
 #  define GTEST_OS_WINDOWS_MOBILE 1
-# elif defined(__MINGW__) || defined(__MINGW32__)
-#  define GTEST_OS_WINDOWS_MINGW 1
 # elif defined(WINAPI_FAMILY)
 #  include <winapifamily.h>
 #  if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
@@ -430,6 +432,9 @@
 #   define GTEST_OS_WINDOWS_PHONE 1
 #  elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
 #   define GTEST_OS_WINDOWS_RT 1
+#  elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
+#   define GTEST_OS_WINDOWS_PHONE 1
+#   define GTEST_OS_WINDOWS_TV_TITLE 1
 #  else
     // WINAPI_FAMILY defined but no known partition matched.
     // Default to desktop.
@@ -438,13 +443,21 @@
 # else
 #  define GTEST_OS_WINDOWS_DESKTOP 1
 # endif  // _WIN32_WCE
+#elif defined __OS2__
+# define GTEST_OS_OS2 1
 #elif defined __APPLE__
 # define GTEST_OS_MAC 1
 # if TARGET_OS_IPHONE
 #  define GTEST_OS_IOS 1
 # endif
+#elif defined __DragonFly__
+# define GTEST_OS_DRAGONFLY 1
 #elif defined __FreeBSD__
 # define GTEST_OS_FREEBSD 1
+#elif defined __Fuchsia__
+# define GTEST_OS_FUCHSIA 1
+#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)
+# define GTEST_OS_GNU_KFREEBSD 1
 #elif defined __linux__
 # define GTEST_OS_LINUX 1
 # if defined __ANDROID__
@@ -460,6 +473,8 @@
 # define GTEST_OS_HPUX 1
 #elif defined __native_client__
 # define GTEST_OS_NACL 1
+#elif defined __NetBSD__
+# define GTEST_OS_NETBSD 1
 #elif defined __OpenBSD__
 # define GTEST_OS_OPENBSD 1
 #elif defined __QNX__
@@ -496,39 +511,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
-// Injection point for custom user configurations.
-// The following macros can be defined:
-//
-//   Flag related macros:
-//     GTEST_FLAG(flag_name)
-//     GTEST_USE_OWN_FLAGFILE_FLAG_  - Define to 0 when the system provides its
-//                                     own flagfile flag parsing.
-//     GTEST_DECLARE_bool_(name)
-//     GTEST_DECLARE_int32_(name)
-//     GTEST_DECLARE_string_(name)
-//     GTEST_DEFINE_bool_(name, default_val, doc)
-//     GTEST_DEFINE_int32_(name, default_val, doc)
-//     GTEST_DEFINE_string_(name, default_val, doc)
-//
-//   Test filtering:
-//     GTEST_TEST_FILTER_ENV_VAR_ - The name of an environment variable that
-//                                  will be used if --GTEST_FLAG(test_filter)
-//                                  is not provided.
-//
-//   Logging:
-//     GTEST_LOG_(severity)
-//     GTEST_CHECK_(condition)
-//     Functions LogToStderr() and FlushInfoLog() have to be provided too.
-//
-//   Threading:
-//     GTEST_HAS_NOTIFICATION_ - Enabled if Notification is already provided.
-//     GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - Enabled if Mutex and ThreadLocal are
-//                                         already provided.
-//     Must also provide GTEST_DECLARE_STATIC_MUTEX_(mutex) and
-//     GTEST_DEFINE_STATIC_MUTEX_(mutex)
-//
-//     GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)
-//     GTEST_LOCK_EXCLUDED_(locks)
+// Injection point for custom user configurations. See README for details
 //
 // ** Custom implementation starts here **
 
@@ -562,85 +545,32 @@
 //   GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385)
 //   /* code that triggers warnings C4800 and C4385 */
 //   GTEST_DISABLE_MSC_WARNINGS_POP_()
-#if _MSC_VER >= 1500
+#if defined(_MSC_VER)
 # define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \
     __pragma(warning(push))                        \
     __pragma(warning(disable: warnings))
 # define GTEST_DISABLE_MSC_WARNINGS_POP_()          \
     __pragma(warning(pop))
 #else
-// Older versions of MSVC don't have __pragma.
+// Not all compilers are MSVC
 # define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings)
 # define GTEST_DISABLE_MSC_WARNINGS_POP_()
 #endif
 
-#ifndef GTEST_LANG_CXX11
-// gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when
-// -std={c,gnu}++{0x,11} is passed.  The C++11 standard specifies a
-// value for __cplusplus, and recent versions of clang, gcc, and
-// probably other compilers set that too in C++11 mode.
-# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L
-// Compiling in at least C++11 mode.
-#  define GTEST_LANG_CXX11 1
-# else
-#  define GTEST_LANG_CXX11 0
-# endif
-#endif
-
-// Distinct from C++11 language support, some environments don't provide
-// proper C++11 library support. Notably, it's possible to build in
-// C++11 mode when targeting Mac OS X 10.6, which has an old libstdc++
-// with no C++11 support.
-//
-// libstdc++ has sufficient C++11 support as of GCC 4.6.0, __GLIBCXX__
-// 20110325, but maintenance releases in the 4.4 and 4.5 series followed
-// this date, so check for those versions by their date stamps.
-// https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html#abi.versioning
-#if GTEST_LANG_CXX11 && \
-    (!defined(__GLIBCXX__) || ( \
-        __GLIBCXX__ >= 20110325ul &&  /* GCC >= 4.6.0 */ \
-        /* Blacklist of patch releases of older branches: */ \
-        __GLIBCXX__ != 20110416ul &&  /* GCC 4.4.6 */ \
-        __GLIBCXX__ != 20120313ul &&  /* GCC 4.4.7 */ \
-        __GLIBCXX__ != 20110428ul &&  /* GCC 4.5.3 */ \
-        __GLIBCXX__ != 20120702ul))   /* GCC 4.5.4 */
-# define GTEST_STDLIB_CXX11 1
-#endif
-
-// Only use C++11 library features if the library provides them.
-#if GTEST_STDLIB_CXX11
-# define GTEST_HAS_STD_BEGIN_AND_END_ 1
-# define GTEST_HAS_STD_FORWARD_LIST_ 1
-# define GTEST_HAS_STD_FUNCTION_ 1
-# define GTEST_HAS_STD_INITIALIZER_LIST_ 1
-# define GTEST_HAS_STD_MOVE_ 1
-# define GTEST_HAS_STD_SHARED_PTR_ 1
-# define GTEST_HAS_STD_TYPE_TRAITS_ 1
-# define GTEST_HAS_STD_UNIQUE_PTR_ 1
-#endif
-
-// C++11 specifies that <tuple> provides std::tuple.
-// Some platforms still might not have it, however.
-#if GTEST_LANG_CXX11
-# define GTEST_HAS_STD_TUPLE_ 1
-# if defined(__clang__)
-// Inspired by http://clang.llvm.org/docs/LanguageExtensions.html#__has_include
-#  if defined(__has_include) && !__has_include(<tuple>)
-#   undef GTEST_HAS_STD_TUPLE_
-#  endif
-# elif defined(_MSC_VER)
-// Inspired by boost/config/stdlib/dinkumware.hpp
-#  if defined(_CPPLIB_VER) && _CPPLIB_VER < 520
-#   undef GTEST_HAS_STD_TUPLE_
-#  endif
-# elif defined(__GLIBCXX__)
-// Inspired by boost/config/stdlib/libstdcpp3.hpp,
-// http://gcc.gnu.org/gcc-4.2/changes.html and
-// http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt01ch01.html#manual.intro.status.standard.200x
-#  if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)
-#   undef GTEST_HAS_STD_TUPLE_
-#  endif
-# endif
+// Clang on Windows does not understand MSVC's pragma warning.
+// We need clang-specific way to disable function deprecation warning.
+#ifdef __clang__
+# define GTEST_DISABLE_MSC_DEPRECATED_PUSH_()                         \
+    _Pragma("clang diagnostic push")                                  \
+    _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \
+    _Pragma("clang diagnostic ignored \"-Wdeprecated-implementations\"")
+#define GTEST_DISABLE_MSC_DEPRECATED_POP_() \
+    _Pragma("clang diagnostic pop")
+#else
+# define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \
+    GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
+# define GTEST_DISABLE_MSC_DEPRECATED_POP_() \
+    GTEST_DISABLE_MSC_WARNINGS_POP_()
 #endif
 
 // Brings in definitions for functions used in the testing::internal::posix
@@ -715,8 +645,11 @@
 #ifndef GTEST_HAS_EXCEPTIONS
 // The user didn't tell us whether exceptions are enabled, so we need
 // to figure it out.
-# if defined(_MSC_VER) || defined(__BORLANDC__)
-// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS
+# if defined(_MSC_VER) && defined(_CPPUNWIND)
+// MSVC defines _CPPUNWIND to 1 iff exceptions are enabled.
+#  define GTEST_HAS_EXCEPTIONS 1
+# elif defined(__BORLANDC__)
+// C++Builder's implementation of the STL uses the _HAS_EXCEPTIONS
 // macro to enable exceptions, so we'll do the same.
 // Assumes that exceptions are enabled by default.
 #  ifndef _HAS_EXCEPTIONS
@@ -760,23 +693,16 @@
 # define GTEST_HAS_STD_STRING 1
 #elif !GTEST_HAS_STD_STRING
 // The user told us that ::std::string isn't available.
-# error "Google Test cannot be used where ::std::string isn't available."
+# error "::std::string isn't available."
 #endif  // !defined(GTEST_HAS_STD_STRING)
 
 #ifndef GTEST_HAS_GLOBAL_STRING
-// The user didn't tell us whether ::string is available, so we need
-// to figure it out.
-
 # define GTEST_HAS_GLOBAL_STRING 0
-
 #endif  // GTEST_HAS_GLOBAL_STRING
 
 #ifndef GTEST_HAS_STD_WSTRING
 // The user didn't tell us whether ::std::wstring is available, so we need
 // to figure it out.
-// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring
-//   is available.
-
 // Cygwin 1.7 and below doesn't support ::std::wstring.
 // Solaris' libc++ doesn't support it either.  Android has
 // no support for it at least as recent as Froyo (2.2).
@@ -806,7 +732,7 @@
 #  endif
 
 // Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled.
-# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302)
+# elif defined(__GNUC__)
 
 #  ifdef __GXX_RTTI
 // When building against STLport with the Android NDK and with
@@ -862,8 +788,10 @@
 //
 // To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
 // to your compiler flags.
-# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \
-    || GTEST_OS_QNX || GTEST_OS_FREEBSD || GTEST_OS_NACL)
+#define GTEST_HAS_PTHREAD                                             \
+  (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \
+   GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
+   GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_OPENBSD)
 #endif  // GTEST_HAS_PTHREAD
 
 #if GTEST_HAS_PTHREAD
@@ -875,1157 +803,6 @@
 # include <time.h>  // NOLINT
 #endif
 
-// Determines if hash_map/hash_set are available.
-// Only used for testing against those containers.
-#if !defined(GTEST_HAS_HASH_MAP_)
-# if _MSC_VER
-#  define GTEST_HAS_HASH_MAP_ 1  // Indicates that hash_map is available.
-#  define GTEST_HAS_HASH_SET_ 1  // Indicates that hash_set is available.
-# endif  // _MSC_VER
-#endif  // !defined(GTEST_HAS_HASH_MAP_)
-
-// Determines whether Google Test can use tr1/tuple.  You can define
-// this macro to 0 to prevent Google Test from using tuple (any
-// feature depending on tuple with be disabled in this mode).
-#ifndef GTEST_HAS_TR1_TUPLE
-# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR)
-// STLport, provided with the Android NDK, has neither <tr1/tuple> or <tuple>.
-#  define GTEST_HAS_TR1_TUPLE 0
-# else
-// The user didn't tell us not to do it, so we assume it's OK.
-#  define GTEST_HAS_TR1_TUPLE 1
-# endif
-#endif  // GTEST_HAS_TR1_TUPLE
-
-// Determines whether Google Test's own tr1 tuple implementation
-// should be used.
-#ifndef GTEST_USE_OWN_TR1_TUPLE
-// The user didn't tell us, so we need to figure it out.
-
-// We use our own TR1 tuple if we aren't sure the user has an
-// implementation of it already.  At this time, libstdc++ 4.0.0+ and
-// MSVC 2010 are the only mainstream standard libraries that come
-// with a TR1 tuple implementation.  NVIDIA's CUDA NVCC compiler
-// pretends to be GCC by defining __GNUC__ and friends, but cannot
-// compile GCC's tuple implementation.  MSVC 2008 (9.0) provides TR1
-// tuple in a 323 MB Feature Pack download, which we cannot assume the
-// user has.  QNX's QCC compiler is a modified GCC but it doesn't
-// support TR1 tuple.  libc++ only provides std::tuple, in C++11 mode,
-// and it can be used with some compilers that define __GNUC__.
-# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \
-      && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600
-#  define GTEST_ENV_HAS_TR1_TUPLE_ 1
-# endif
-
-// C++11 specifies that <tuple> provides std::tuple. Use that if gtest is used
-// in C++11 mode and libstdc++ isn't very old (binaries targeting OS X 10.6
-// can build with clang but need to use gcc4.2's libstdc++).
-# if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325)
-#  define GTEST_ENV_HAS_STD_TUPLE_ 1
-# endif
-
-# if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_
-#  define GTEST_USE_OWN_TR1_TUPLE 0
-# else
-#  define GTEST_USE_OWN_TR1_TUPLE 1
-# endif
-
-#endif  // GTEST_USE_OWN_TR1_TUPLE
-
-// To avoid conditional compilation everywhere, we make it
-// gtest-port.h's responsibility to #include the header implementing
-// tuple.
-#if GTEST_HAS_STD_TUPLE_
-# include <tuple>  // IWYU pragma: export
-# define GTEST_TUPLE_NAMESPACE_ ::std
-#endif  // GTEST_HAS_STD_TUPLE_
-
-// We include tr1::tuple even if std::tuple is available to define printers for
-// them.
-#if GTEST_HAS_TR1_TUPLE
-# ifndef GTEST_TUPLE_NAMESPACE_
-#  define GTEST_TUPLE_NAMESPACE_ ::std::tr1
-# endif  // GTEST_TUPLE_NAMESPACE_
-
-# if GTEST_USE_OWN_TR1_TUPLE
-// This file was GENERATED by command:
-//     pump.py gtest-tuple.h.pump
-// DO NOT EDIT BY HAND!!!
-
-// Copyright 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: wan@google.com (Zhanyong Wan)
-
-// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
-
-#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
-#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
-
-#include <utility>  // For ::std::pair.
-
-// The compiler used in Symbian has a bug that prevents us from declaring the
-// tuple template as a friend (it complains that tuple is redefined).  This
-// hack bypasses the bug by declaring the members that should otherwise be
-// private as public.
-// Sun Studio versions < 12 also have the above bug.
-#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
-# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
-#else
-# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
-    template <GTEST_10_TYPENAMES_(U)> friend class tuple; \
-   private:
-#endif
-
-// Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that conflict
-// with our own definitions. Therefore using our own tuple does not work on
-// those compilers.
-#if defined(_MSC_VER) && _MSC_VER >= 1600  /* 1600 is Visual Studio 2010 */
-# error "gtest's tuple doesn't compile on Visual Studio 2010 or later. \
-GTEST_USE_OWN_TR1_TUPLE must be set to 0 on those compilers."
-#endif
-
-// GTEST_n_TUPLE_(T) is the type of an n-tuple.
-#define GTEST_0_TUPLE_(T) tuple<>
-#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
-    void, void, void>
-#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \
-    void, void, void>
-#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \
-    void, void, void>
-#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \
-    void, void, void>
-#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \
-    void, void, void>
-#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \
-    void, void, void>
-#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
-    void, void, void>
-#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
-    T##7, void, void>
-#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
-    T##7, T##8, void>
-#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
-    T##7, T##8, T##9>
-
-// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
-#define GTEST_0_TYPENAMES_(T)
-#define GTEST_1_TYPENAMES_(T) typename T##0
-#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1
-#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2
-#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
-    typename T##3
-#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
-    typename T##3, typename T##4
-#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
-    typename T##3, typename T##4, typename T##5
-#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
-    typename T##3, typename T##4, typename T##5, typename T##6
-#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
-    typename T##3, typename T##4, typename T##5, typename T##6, typename T##7
-#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
-    typename T##3, typename T##4, typename T##5, typename T##6, \
-    typename T##7, typename T##8
-#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
-    typename T##3, typename T##4, typename T##5, typename T##6, \
-    typename T##7, typename T##8, typename T##9
-
-// In theory, defining stuff in the ::std namespace is undefined
-// behavior.  We can do this as we are playing the role of a standard
-// library vendor.
-namespace std {
-namespace tr1 {
-
-template <typename T0 = void, typename T1 = void, typename T2 = void,
-    typename T3 = void, typename T4 = void, typename T5 = void,
-    typename T6 = void, typename T7 = void, typename T8 = void,
-    typename T9 = void>
-class tuple;
-
-// Anything in namespace gtest_internal is Google Test's INTERNAL
-// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
-namespace gtest_internal {
-
-// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
-template <typename T>
-struct ByRef { typedef const T& type; };  // NOLINT
-template <typename T>
-struct ByRef<T&> { typedef T& type; };  // NOLINT
-
-// A handy wrapper for ByRef.
-#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
-
-// AddRef<T>::type is T if T is a reference; otherwise it's T&.  This
-// is the same as tr1::add_reference<T>::type.
-template <typename T>
-struct AddRef { typedef T& type; };  // NOLINT
-template <typename T>
-struct AddRef<T&> { typedef T& type; };  // NOLINT
-
-// A handy wrapper for AddRef.
-#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
-
-// A helper for implementing get<k>().
-template <int k> class Get;
-
-// A helper for implementing tuple_element<k, T>.  kIndexValid is true
-// iff k < the number of fields in tuple type T.
-template <bool kIndexValid, int kIndex, class Tuple>
-struct TupleElement;
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 0, GTEST_10_TUPLE_(T) > {
-  typedef T0 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 1, GTEST_10_TUPLE_(T) > {
-  typedef T1 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 2, GTEST_10_TUPLE_(T) > {
-  typedef T2 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 3, GTEST_10_TUPLE_(T) > {
-  typedef T3 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 4, GTEST_10_TUPLE_(T) > {
-  typedef T4 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 5, GTEST_10_TUPLE_(T) > {
-  typedef T5 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 6, GTEST_10_TUPLE_(T) > {
-  typedef T6 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 7, GTEST_10_TUPLE_(T) > {
-  typedef T7 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 8, GTEST_10_TUPLE_(T) > {
-  typedef T8 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 9, GTEST_10_TUPLE_(T) > {
-  typedef T9 type;
-};
-
-}  // namespace gtest_internal
-
-template <>
-class tuple<> {
- public:
-  tuple() {}
-  tuple(const tuple& /* t */)  {}
-  tuple& operator=(const tuple& /* t */) { return *this; }
-};
-
-template <GTEST_1_TYPENAMES_(T)>
-class GTEST_1_TUPLE_(T) {
- public:
-  template <int k> friend class gtest_internal::Get;
-
-  tuple() : f0_() {}
-
-  explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}
-
-  tuple(const tuple& t) : f0_(t.f0_) {}
-
-  template <GTEST_1_TYPENAMES_(U)>
-  tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {}
-
-  tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
-  template <GTEST_1_TYPENAMES_(U)>
-  tuple& operator=(const GTEST_1_TUPLE_(U)& t) {
-    return CopyFrom(t);
-  }
-
-  GTEST_DECLARE_TUPLE_AS_FRIEND_
-
-  template <GTEST_1_TYPENAMES_(U)>
-  tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {
-    f0_ = t.f0_;
-    return *this;
-  }
-
-  T0 f0_;
-};
-
-template <GTEST_2_TYPENAMES_(T)>
-class GTEST_2_TUPLE_(T) {
- public:
-  template <int k> friend class gtest_internal::Get;
-
-  tuple() : f0_(), f1_() {}
-
-  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),
-      f1_(f1) {}
-
-  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {}
-
-  template <GTEST_2_TYPENAMES_(U)>
-  tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {}
-  template <typename U0, typename U1>
-  tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
-
-  tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
-  template <GTEST_2_TYPENAMES_(U)>
-  tuple& operator=(const GTEST_2_TUPLE_(U)& t) {
-    return CopyFrom(t);
-  }
-  template <typename U0, typename U1>
-  tuple& operator=(const ::std::pair<U0, U1>& p) {
-    f0_ = p.first;
-    f1_ = p.second;
-    return *this;
-  }
-
-  GTEST_DECLARE_TUPLE_AS_FRIEND_
-
-  template <GTEST_2_TYPENAMES_(U)>
-  tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {
-    f0_ = t.f0_;
-    f1_ = t.f1_;
-    return *this;
-  }
-
-  T0 f0_;
-  T1 f1_;
-};
-
-template <GTEST_3_TYPENAMES_(T)>
-class GTEST_3_TUPLE_(T) {
- public:
-  template <int k> friend class gtest_internal::Get;
-
-  tuple() : f0_(), f1_(), f2_() {}
-
-  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
-      GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}
-
-  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
-
-  template <GTEST_3_TYPENAMES_(U)>
-  tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
-
-  tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
-  template <GTEST_3_TYPENAMES_(U)>
-  tuple& operator=(const GTEST_3_TUPLE_(U)& t) {
-    return CopyFrom(t);
-  }
-
-  GTEST_DECLARE_TUPLE_AS_FRIEND_
-
-  template <GTEST_3_TYPENAMES_(U)>
-  tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {
-    f0_ = t.f0_;
-    f1_ = t.f1_;
-    f2_ = t.f2_;
-    return *this;
-  }
-
-  T0 f0_;
-  T1 f1_;
-  T2 f2_;
-};
-
-template <GTEST_4_TYPENAMES_(T)>
-class GTEST_4_TUPLE_(T) {
- public:
-  template <int k> friend class gtest_internal::Get;
-
-  tuple() : f0_(), f1_(), f2_(), f3_() {}
-
-  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
-      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),
-      f3_(f3) {}
-
-  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {}
-
-  template <GTEST_4_TYPENAMES_(U)>
-  tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
-      f3_(t.f3_) {}
-
-  tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
-  template <GTEST_4_TYPENAMES_(U)>
-  tuple& operator=(const GTEST_4_TUPLE_(U)& t) {
-    return CopyFrom(t);
-  }
-
-  GTEST_DECLARE_TUPLE_AS_FRIEND_
-
-  template <GTEST_4_TYPENAMES_(U)>
-  tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {
-    f0_ = t.f0_;
-    f1_ = t.f1_;
-    f2_ = t.f2_;
-    f3_ = t.f3_;
-    return *this;
-  }
-
-  T0 f0_;
-  T1 f1_;
-  T2 f2_;
-  T3 f3_;
-};
-
-template <GTEST_5_TYPENAMES_(T)>
-class GTEST_5_TUPLE_(T) {
- public:
-  template <int k> friend class gtest_internal::Get;
-
-  tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {}
-
-  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
-      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,
-      GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {}
-
-  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
-      f4_(t.f4_) {}
-
-  template <GTEST_5_TYPENAMES_(U)>
-  tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
-      f3_(t.f3_), f4_(t.f4_) {}
-
-  tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
-  template <GTEST_5_TYPENAMES_(U)>
-  tuple& operator=(const GTEST_5_TUPLE_(U)& t) {
-    return CopyFrom(t);
-  }
-
-  GTEST_DECLARE_TUPLE_AS_FRIEND_
-
-  template <GTEST_5_TYPENAMES_(U)>
-  tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {
-    f0_ = t.f0_;
-    f1_ = t.f1_;
-    f2_ = t.f2_;
-    f3_ = t.f3_;
-    f4_ = t.f4_;
-    return *this;
-  }
-
-  T0 f0_;
-  T1 f1_;
-  T2 f2_;
-  T3 f3_;
-  T4 f4_;
-};
-
-template <GTEST_6_TYPENAMES_(T)>
-class GTEST_6_TUPLE_(T) {
- public:
-  template <int k> friend class gtest_internal::Get;
-
-  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {}
-
-  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
-      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
-      GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
-      f5_(f5) {}
-
-  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
-      f4_(t.f4_), f5_(t.f5_) {}
-
-  template <GTEST_6_TYPENAMES_(U)>
-  tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
-      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {}
-
-  tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
-  template <GTEST_6_TYPENAMES_(U)>
-  tuple& operator=(const GTEST_6_TUPLE_(U)& t) {
-    return CopyFrom(t);
-  }
-
-  GTEST_DECLARE_TUPLE_AS_FRIEND_
-
-  template <GTEST_6_TYPENAMES_(U)>
-  tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {
-    f0_ = t.f0_;
-    f1_ = t.f1_;
-    f2_ = t.f2_;
-    f3_ = t.f3_;
-    f4_ = t.f4_;
-    f5_ = t.f5_;
-    return *this;
-  }
-
-  T0 f0_;
-  T1 f1_;
-  T2 f2_;
-  T3 f3_;
-  T4 f4_;
-  T5 f5_;
-};
-
-template <GTEST_7_TYPENAMES_(T)>
-class GTEST_7_TUPLE_(T) {
- public:
-  template <int k> friend class gtest_internal::Get;
-
-  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {}
-
-  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
-      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
-      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2),
-      f3_(f3), f4_(f4), f5_(f5), f6_(f6) {}
-
-  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
-      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
-
-  template <GTEST_7_TYPENAMES_(U)>
-  tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
-      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
-
-  tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
-  template <GTEST_7_TYPENAMES_(U)>
-  tuple& operator=(const GTEST_7_TUPLE_(U)& t) {
-    return CopyFrom(t);
-  }
-
-  GTEST_DECLARE_TUPLE_AS_FRIEND_
-
-  template <GTEST_7_TYPENAMES_(U)>
-  tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {
-    f0_ = t.f0_;
-    f1_ = t.f1_;
-    f2_ = t.f2_;
-    f3_ = t.f3_;
-    f4_ = t.f4_;
-    f5_ = t.f5_;
-    f6_ = t.f6_;
-    return *this;
-  }
-
-  T0 f0_;
-  T1 f1_;
-  T2 f2_;
-  T3 f3_;
-  T4 f4_;
-  T5 f5_;
-  T6 f6_;
-};
-
-template <GTEST_8_TYPENAMES_(T)>
-class GTEST_8_TUPLE_(T) {
- public:
-  template <int k> friend class gtest_internal::Get;
-
-  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {}
-
-  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
-      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
-      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6,
-      GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
-      f5_(f5), f6_(f6), f7_(f7) {}
-
-  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
-      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
-
-  template <GTEST_8_TYPENAMES_(U)>
-  tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
-      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
-
-  tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
-  template <GTEST_8_TYPENAMES_(U)>
-  tuple& operator=(const GTEST_8_TUPLE_(U)& t) {
-    return CopyFrom(t);
-  }
-
-  GTEST_DECLARE_TUPLE_AS_FRIEND_
-
-  template <GTEST_8_TYPENAMES_(U)>
-  tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {
-    f0_ = t.f0_;
-    f1_ = t.f1_;
-    f2_ = t.f2_;
-    f3_ = t.f3_;
-    f4_ = t.f4_;
-    f5_ = t.f5_;
-    f6_ = t.f6_;
-    f7_ = t.f7_;
-    return *this;
-  }
-
-  T0 f0_;
-  T1 f1_;
-  T2 f2_;
-  T3 f3_;
-  T4 f4_;
-  T5 f5_;
-  T6 f6_;
-  T7 f7_;
-};
-
-template <GTEST_9_TYPENAMES_(T)>
-class GTEST_9_TUPLE_(T) {
- public:
-  template <int k> friend class gtest_internal::Get;
-
-  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {}
-
-  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
-      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
-      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
-      GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
-      f5_(f5), f6_(f6), f7_(f7), f8_(f8) {}
-
-  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
-      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
-
-  template <GTEST_9_TYPENAMES_(U)>
-  tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
-      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
-
-  tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
-  template <GTEST_9_TYPENAMES_(U)>
-  tuple& operator=(const GTEST_9_TUPLE_(U)& t) {
-    return CopyFrom(t);
-  }
-
-  GTEST_DECLARE_TUPLE_AS_FRIEND_
-
-  template <GTEST_9_TYPENAMES_(U)>
-  tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {
-    f0_ = t.f0_;
-    f1_ = t.f1_;
-    f2_ = t.f2_;
-    f3_ = t.f3_;
-    f4_ = t.f4_;
-    f5_ = t.f5_;
-    f6_ = t.f6_;
-    f7_ = t.f7_;
-    f8_ = t.f8_;
-    return *this;
-  }
-
-  T0 f0_;
-  T1 f1_;
-  T2 f2_;
-  T3 f3_;
-  T4 f4_;
-  T5 f5_;
-  T6 f6_;
-  T7 f7_;
-  T8 f8_;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-class tuple {
- public:
-  template <int k> friend class gtest_internal::Get;
-
-  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(),
-      f9_() {}
-
-  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
-      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
-      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
-      GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2),
-      f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {}
-
-  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
-      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {}
-
-  template <GTEST_10_TYPENAMES_(U)>
-  tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
-      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_),
-      f9_(t.f9_) {}
-
-  tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
-  template <GTEST_10_TYPENAMES_(U)>
-  tuple& operator=(const GTEST_10_TUPLE_(U)& t) {
-    return CopyFrom(t);
-  }
-
-  GTEST_DECLARE_TUPLE_AS_FRIEND_
-
-  template <GTEST_10_TYPENAMES_(U)>
-  tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {
-    f0_ = t.f0_;
-    f1_ = t.f1_;
-    f2_ = t.f2_;
-    f3_ = t.f3_;
-    f4_ = t.f4_;
-    f5_ = t.f5_;
-    f6_ = t.f6_;
-    f7_ = t.f7_;
-    f8_ = t.f8_;
-    f9_ = t.f9_;
-    return *this;
-  }
-
-  T0 f0_;
-  T1 f1_;
-  T2 f2_;
-  T3 f3_;
-  T4 f4_;
-  T5 f5_;
-  T6 f6_;
-  T7 f7_;
-  T8 f8_;
-  T9 f9_;
-};
-
-// 6.1.3.2 Tuple creation functions.
-
-// Known limitations: we don't support passing an
-// std::tr1::reference_wrapper<T> to make_tuple().  And we don't
-// implement tie().
-
-inline tuple<> make_tuple() { return tuple<>(); }
-
-template <GTEST_1_TYPENAMES_(T)>
-inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) {
-  return GTEST_1_TUPLE_(T)(f0);
-}
-
-template <GTEST_2_TYPENAMES_(T)>
-inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) {
-  return GTEST_2_TUPLE_(T)(f0, f1);
-}
-
-template <GTEST_3_TYPENAMES_(T)>
-inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) {
-  return GTEST_3_TUPLE_(T)(f0, f1, f2);
-}
-
-template <GTEST_4_TYPENAMES_(T)>
-inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
-    const T3& f3) {
-  return GTEST_4_TUPLE_(T)(f0, f1, f2, f3);
-}
-
-template <GTEST_5_TYPENAMES_(T)>
-inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
-    const T3& f3, const T4& f4) {
-  return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4);
-}
-
-template <GTEST_6_TYPENAMES_(T)>
-inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
-    const T3& f3, const T4& f4, const T5& f5) {
-  return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5);
-}
-
-template <GTEST_7_TYPENAMES_(T)>
-inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
-    const T3& f3, const T4& f4, const T5& f5, const T6& f6) {
-  return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6);
-}
-
-template <GTEST_8_TYPENAMES_(T)>
-inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
-    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) {
-  return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7);
-}
-
-template <GTEST_9_TYPENAMES_(T)>
-inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
-    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
-    const T8& f8) {
-  return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8);
-}
-
-template <GTEST_10_TYPENAMES_(T)>
-inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
-    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
-    const T8& f8, const T9& f9) {
-  return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9);
-}
-
-// 6.1.3.3 Tuple helper classes.
-
-template <typename Tuple> struct tuple_size;
-
-template <GTEST_0_TYPENAMES_(T)>
-struct tuple_size<GTEST_0_TUPLE_(T) > {
-  static const int value = 0;
-};
-
-template <GTEST_1_TYPENAMES_(T)>
-struct tuple_size<GTEST_1_TUPLE_(T) > {
-  static const int value = 1;
-};
-
-template <GTEST_2_TYPENAMES_(T)>
-struct tuple_size<GTEST_2_TUPLE_(T) > {
-  static const int value = 2;
-};
-
-template <GTEST_3_TYPENAMES_(T)>
-struct tuple_size<GTEST_3_TUPLE_(T) > {
-  static const int value = 3;
-};
-
-template <GTEST_4_TYPENAMES_(T)>
-struct tuple_size<GTEST_4_TUPLE_(T) > {
-  static const int value = 4;
-};
-
-template <GTEST_5_TYPENAMES_(T)>
-struct tuple_size<GTEST_5_TUPLE_(T) > {
-  static const int value = 5;
-};
-
-template <GTEST_6_TYPENAMES_(T)>
-struct tuple_size<GTEST_6_TUPLE_(T) > {
-  static const int value = 6;
-};
-
-template <GTEST_7_TYPENAMES_(T)>
-struct tuple_size<GTEST_7_TUPLE_(T) > {
-  static const int value = 7;
-};
-
-template <GTEST_8_TYPENAMES_(T)>
-struct tuple_size<GTEST_8_TUPLE_(T) > {
-  static const int value = 8;
-};
-
-template <GTEST_9_TYPENAMES_(T)>
-struct tuple_size<GTEST_9_TUPLE_(T) > {
-  static const int value = 9;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct tuple_size<GTEST_10_TUPLE_(T) > {
-  static const int value = 10;
-};
-
-template <int k, class Tuple>
-struct tuple_element {
-  typedef typename gtest_internal::TupleElement<
-      k < (tuple_size<Tuple>::value), k, Tuple>::type type;
-};
-
-#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
-
-// 6.1.3.4 Element access.
-
-namespace gtest_internal {
-
-template <>
-class Get<0> {
- public:
-  template <class Tuple>
-  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
-  Field(Tuple& t) { return t.f0_; }  // NOLINT
-
-  template <class Tuple>
-  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
-  ConstField(const Tuple& t) { return t.f0_; }
-};
-
-template <>
-class Get<1> {
- public:
-  template <class Tuple>
-  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
-  Field(Tuple& t) { return t.f1_; }  // NOLINT
-
-  template <class Tuple>
-  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
-  ConstField(const Tuple& t) { return t.f1_; }
-};
-
-template <>
-class Get<2> {
- public:
-  template <class Tuple>
-  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
-  Field(Tuple& t) { return t.f2_; }  // NOLINT
-
-  template <class Tuple>
-  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
-  ConstField(const Tuple& t) { return t.f2_; }
-};
-
-template <>
-class Get<3> {
- public:
-  template <class Tuple>
-  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
-  Field(Tuple& t) { return t.f3_; }  // NOLINT
-
-  template <class Tuple>
-  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
-  ConstField(const Tuple& t) { return t.f3_; }
-};
-
-template <>
-class Get<4> {
- public:
-  template <class Tuple>
-  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
-  Field(Tuple& t) { return t.f4_; }  // NOLINT
-
-  template <class Tuple>
-  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
-  ConstField(const Tuple& t) { return t.f4_; }
-};
-
-template <>
-class Get<5> {
- public:
-  template <class Tuple>
-  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
-  Field(Tuple& t) { return t.f5_; }  // NOLINT
-
-  template <class Tuple>
-  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
-  ConstField(const Tuple& t) { return t.f5_; }
-};
-
-template <>
-class Get<6> {
- public:
-  template <class Tuple>
-  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
-  Field(Tuple& t) { return t.f6_; }  // NOLINT
-
-  template <class Tuple>
-  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
-  ConstField(const Tuple& t) { return t.f6_; }
-};
-
-template <>
-class Get<7> {
- public:
-  template <class Tuple>
-  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
-  Field(Tuple& t) { return t.f7_; }  // NOLINT
-
-  template <class Tuple>
-  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
-  ConstField(const Tuple& t) { return t.f7_; }
-};
-
-template <>
-class Get<8> {
- public:
-  template <class Tuple>
-  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
-  Field(Tuple& t) { return t.f8_; }  // NOLINT
-
-  template <class Tuple>
-  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
-  ConstField(const Tuple& t) { return t.f8_; }
-};
-
-template <>
-class Get<9> {
- public:
-  template <class Tuple>
-  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
-  Field(Tuple& t) { return t.f9_; }  // NOLINT
-
-  template <class Tuple>
-  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
-  ConstField(const Tuple& t) { return t.f9_; }
-};
-
-}  // namespace gtest_internal
-
-template <int k, GTEST_10_TYPENAMES_(T)>
-GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
-get(GTEST_10_TUPLE_(T)& t) {
-  return gtest_internal::Get<k>::Field(t);
-}
-
-template <int k, GTEST_10_TYPENAMES_(T)>
-GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k,  GTEST_10_TUPLE_(T)))
-get(const GTEST_10_TUPLE_(T)& t) {
-  return gtest_internal::Get<k>::ConstField(t);
-}
-
-// 6.1.3.5 Relational operators
-
-// We only implement == and !=, as we don't have a need for the rest yet.
-
-namespace gtest_internal {
-
-// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
-// first k fields of t1 equals the first k fields of t2.
-// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
-// k1 != k2.
-template <int kSize1, int kSize2>
-struct SameSizeTuplePrefixComparator;
-
-template <>
-struct SameSizeTuplePrefixComparator<0, 0> {
-  template <class Tuple1, class Tuple2>
-  static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
-    return true;
-  }
-};
-
-template <int k>
-struct SameSizeTuplePrefixComparator<k, k> {
-  template <class Tuple1, class Tuple2>
-  static bool Eq(const Tuple1& t1, const Tuple2& t2) {
-    return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
-        ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
-  }
-};
-
-}  // namespace gtest_internal
-
-template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
-inline bool operator==(const GTEST_10_TUPLE_(T)& t,
-                       const GTEST_10_TUPLE_(U)& u) {
-  return gtest_internal::SameSizeTuplePrefixComparator<
-      tuple_size<GTEST_10_TUPLE_(T) >::value,
-      tuple_size<GTEST_10_TUPLE_(U) >::value>::Eq(t, u);
-}
-
-template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
-inline bool operator!=(const GTEST_10_TUPLE_(T)& t,
-                       const GTEST_10_TUPLE_(U)& u) { return !(t == u); }
-
-// 6.1.4 Pairs.
-// Unimplemented.
-
-}  // namespace tr1
-}  // namespace std
-
-#undef GTEST_0_TUPLE_
-#undef GTEST_1_TUPLE_
-#undef GTEST_2_TUPLE_
-#undef GTEST_3_TUPLE_
-#undef GTEST_4_TUPLE_
-#undef GTEST_5_TUPLE_
-#undef GTEST_6_TUPLE_
-#undef GTEST_7_TUPLE_
-#undef GTEST_8_TUPLE_
-#undef GTEST_9_TUPLE_
-#undef GTEST_10_TUPLE_
-
-#undef GTEST_0_TYPENAMES_
-#undef GTEST_1_TYPENAMES_
-#undef GTEST_2_TYPENAMES_
-#undef GTEST_3_TYPENAMES_
-#undef GTEST_4_TYPENAMES_
-#undef GTEST_5_TYPENAMES_
-#undef GTEST_6_TYPENAMES_
-#undef GTEST_7_TYPENAMES_
-#undef GTEST_8_TYPENAMES_
-#undef GTEST_9_TYPENAMES_
-#undef GTEST_10_TYPENAMES_
-
-#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
-#undef GTEST_BY_REF_
-#undef GTEST_ADD_REF_
-#undef GTEST_TUPLE_ELEMENT_
-
-#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
-# elif GTEST_ENV_HAS_STD_TUPLE_
-#  include <tuple>
-// C++11 puts its tuple into the ::std namespace rather than
-// ::std::tr1.  gtest expects tuple to live in ::std::tr1, so put it there.
-// This causes undefined behavior, but supported compilers react in
-// the way we intend.
-namespace std {
-namespace tr1 {
-using ::std::get;
-using ::std::make_tuple;
-using ::std::tuple;
-using ::std::tuple_element;
-using ::std::tuple_size;
-}
-}
-
-# elif GTEST_OS_SYMBIAN
-
-// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to
-// use STLport's tuple implementation, which unfortunately doesn't
-// work as the copy of STLport distributed with Symbian is incomplete.
-// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to
-// use its own tuple implementation.
-#  ifdef BOOST_HAS_TR1_TUPLE
-#   undef BOOST_HAS_TR1_TUPLE
-#  endif  // BOOST_HAS_TR1_TUPLE
-
-// This prevents <boost/tr1/detail/config.hpp>, which defines
-// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>.
-#  define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
-#  include <tuple>  // IWYU pragma: export  // NOLINT
-
-# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
-// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header.  This does
-// not conform to the TR1 spec, which requires the header to be <tuple>.
-
-#  if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
-// Until version 4.3.2, gcc has a bug that causes <tr1/functional>,
-// which is #included by <tr1/tuple>, to not compile when RTTI is
-// disabled.  _TR1_FUNCTIONAL is the header guard for
-// <tr1/functional>.  Hence the following #define is a hack to prevent
-// <tr1/functional> from being included.
-#   define _TR1_FUNCTIONAL 1
-#   include <tr1/tuple>
-#   undef _TR1_FUNCTIONAL  // Allows the user to #include
-                        // <tr1/functional> if he chooses to.
-#  else
-#   include <tr1/tuple>  // NOLINT
-#  endif  // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
-
-# else
-// If the compiler is not GCC 4.0+, we assume the user is using a
-// spec-conforming TR1 implementation.
-#  include <tuple>  // IWYU pragma: export  // NOLINT
-# endif  // GTEST_USE_OWN_TR1_TUPLE
-
-#endif  // GTEST_HAS_TR1_TUPLE
-
 // Determines whether clone(2) is supported.
 // Usually it will only be available on Linux, excluding
 // Linux on the Itanium architecture.
@@ -2059,55 +836,42 @@
 #ifndef GTEST_HAS_STREAM_REDIRECTION
 // By default, we assume that stream redirection is supported on all
 // platforms except known mobile ones.
-# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || \
-    GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
+# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
 #  define GTEST_HAS_STREAM_REDIRECTION 0
 # else
 #  define GTEST_HAS_STREAM_REDIRECTION 1
-# endif  // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN
+# endif  // !GTEST_OS_WINDOWS_MOBILE
 #endif  // GTEST_HAS_STREAM_REDIRECTION
 
 // Determines whether to support death tests.
-// Google Test does not support death tests for VC 7.1 and earlier as
-// abort() in a VC 7.1 application compiled as GUI in debug config
 // pops up a dialog window that cannot be suppressed programmatically.
-#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
-     (GTEST_OS_MAC && !GTEST_OS_IOS) || \
-     (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
+#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS ||   \
+     (GTEST_OS_MAC && !GTEST_OS_IOS) ||                         \
+     (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER) ||                  \
      GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \
-     GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD)
+     GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD || \
+     GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || GTEST_OS_DRAGONFLY || \
+     GTEST_OS_GNU_KFREEBSD)
 # define GTEST_HAS_DEATH_TEST 1
 #endif
 
-// We don't support MSVC 7.1 with exceptions disabled now.  Therefore
-// all the compilers we care about are adequate for supporting
-// value-parameterized tests.
-#define GTEST_HAS_PARAM_TEST 1
-
 // Determines whether to support type-driven tests.
 
 // Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
 // Sun Pro CC, IBM Visual Age, and HP aCC support.
-#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \
+#if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC) || \
     defined(__IBMCPP__) || defined(__HP_aCC)
 # define GTEST_HAS_TYPED_TEST 1
 # define GTEST_HAS_TYPED_TEST_P 1
 #endif
 
-// Determines whether to support Combine(). This only makes sense when
-// value-parameterized tests are enabled.  The implementation doesn't
-// work on Sun Studio since it doesn't understand templated conversion
-// operators.
-#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC)
-# define GTEST_HAS_COMBINE 1
-#endif
-
 // Determines whether the system compiler uses UTF-16 for encoding wide strings.
 #define GTEST_WIDE_STRING_USES_UTF16_ \
-    (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX)
+  (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_AIX || GTEST_OS_OS2)
 
 // Determines whether test results can be streamed to a socket.
-#if GTEST_OS_LINUX
+#if GTEST_OS_LINUX || GTEST_OS_GNU_KFREEBSD || GTEST_OS_DRAGONFLY || \
+    GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_OPENBSD
 # define GTEST_CAN_STREAM_RESULTS_ 1
 #endif
 
@@ -2149,15 +913,33 @@
 # define GTEST_ATTRIBUTE_UNUSED_
 #endif
 
+// Use this annotation before a function that takes a printf format string.
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(COMPILER_ICC)
+# if defined(__MINGW_PRINTF_FORMAT)
+// MinGW has two different printf implementations. Ensure the format macro
+// matches the selected implementation. See
+// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/.
+#  define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
+       __attribute__((__format__(__MINGW_PRINTF_FORMAT, string_index, \
+                                 first_to_check)))
+# else
+#  define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
+       __attribute__((__format__(__printf__, string_index, first_to_check)))
+# endif
+#else
+# define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
+#endif
+
+
 // A macro to disallow operator=
 // This should be used in the private: declarations for a class.
-#define GTEST_DISALLOW_ASSIGN_(type)\
-  void operator=(type const &)
+#define GTEST_DISALLOW_ASSIGN_(type) \
+  void operator=(type const &) = delete
 
 // A macro to disallow copy constructor and operator=
 // This should be used in the private: declarations for a class.
-#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\
-  type(type const &);\
+#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type) \
+  type(type const &) = delete; \
   GTEST_DISALLOW_ASSIGN_(type)
 
 // Tell the compiler to warn about unused return values for functions declared
@@ -2165,11 +947,11 @@
 // following the argument list:
 //
 //   Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;
-#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC)
+#if defined(__GNUC__) && !defined(COMPILER_ICC)
 # define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result))
 #else
 # define GTEST_MUST_USE_RESULT_
-#endif  // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC
+#endif  // __GNUC__ && !COMPILER_ICC
 
 // MS C++ compiler emits warning when a conditional expression is compile time
 // constant. In some contexts this warning is false positive and needs to be
@@ -2198,13 +980,22 @@
 #  define GTEST_HAS_SEH 0
 # endif
 
-#define GTEST_IS_THREADSAFE \
-    (GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ \
-     || (GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT) \
-     || GTEST_HAS_PTHREAD)
-
 #endif  // GTEST_HAS_SEH
 
+#ifndef GTEST_IS_THREADSAFE
+
+#define GTEST_IS_THREADSAFE                                                 \
+  (GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ ||                                     \
+   (GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT) || \
+   GTEST_HAS_PTHREAD)
+
+#endif  // GTEST_IS_THREADSAFE
+
+// GTEST_API_ qualifies all symbols that must be exported. The definitions below
+// are guarded by #ifndef to give embedders a chance to define GTEST_API_ in
+// gtest/internal/custom/gtest-port.h
+#ifndef GTEST_API_
+
 #ifdef _MSC_VER
 # if GTEST_LINKED_AS_SHARED_LIBRARY
 #  define GTEST_API_ __declspec(dllimport)
@@ -2213,11 +1004,17 @@
 # endif
 #elif __GNUC__ >= 4 || defined(__clang__)
 # define GTEST_API_ __attribute__((visibility ("default")))
-#endif // _MSC_VER
+#endif  // _MSC_VER
+
+#endif  // GTEST_API_
 
 #ifndef GTEST_API_
 # define GTEST_API_
-#endif
+#endif  // GTEST_API_
+
+#ifndef GTEST_DEFAULT_DEATH_TEST_STYLE
+# define GTEST_DEFAULT_DEATH_TEST_STYLE  "fast"
+#endif  // GTEST_DEFAULT_DEATH_TEST_STYLE
 
 #ifdef __GNUC__
 // Ask the compiler to never inline a given function.
@@ -2227,10 +1024,12 @@
 #endif
 
 // _LIBCPP_VERSION is defined by the libc++ library from the LLVM project.
-#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION)
-# define GTEST_HAS_CXXABI_H_ 1
-#else
-# define GTEST_HAS_CXXABI_H_ 0
+#if !defined(GTEST_HAS_CXXABI_H_)
+# if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER))
+#  define GTEST_HAS_CXXABI_H_ 1
+# else
+#  define GTEST_HAS_CXXABI_H_ 0
+# endif
 #endif
 
 // A function level attribute to disable checking for use of uninitialized
@@ -2274,16 +1073,13 @@
 
 class Message;
 
-#if defined(GTEST_TUPLE_NAMESPACE_)
-// Import tuple and friends into the ::testing namespace.
-// It is part of our interface, having them in ::testing allows us to change
-// their types as needed.
-using GTEST_TUPLE_NAMESPACE_::get;
-using GTEST_TUPLE_NAMESPACE_::make_tuple;
-using GTEST_TUPLE_NAMESPACE_::tuple;
-using GTEST_TUPLE_NAMESPACE_::tuple_size;
-using GTEST_TUPLE_NAMESPACE_::tuple_element;
-#endif  // defined(GTEST_TUPLE_NAMESPACE_)
+// Legacy imports for backwards compatibility.
+// New code should use std:: names directly.
+using std::get;
+using std::make_tuple;
+using std::tuple;
+using std::tuple_element;
+using std::tuple_size;
 
 namespace internal {
 
@@ -2292,75 +1088,16 @@
 // Secret object, which is what we want.
 class Secret;
 
-// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time
-// expression is true. For example, you could use it to verify the
-// size of a static array:
+// The GTEST_COMPILE_ASSERT_ is a legacy macro used to verify that a compile
+// time expression is true (in new code, use static_assert instead). For
+// example, you could use it to verify the size of a static array:
 //
 //   GTEST_COMPILE_ASSERT_(GTEST_ARRAY_SIZE_(names) == NUM_NAMES,
 //                         names_incorrect_size);
 //
-// or to make sure a struct is smaller than a certain size:
-//
-//   GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large);
-//
-// The second argument to the macro is the name of the variable. If
-// the expression is false, most compilers will issue a warning/error
-// containing the name of the variable.
-
-#if GTEST_LANG_CXX11
-# define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg)
-#else  // !GTEST_LANG_CXX11
-template <bool>
-  struct CompileAssert {
-};
-
-# define GTEST_COMPILE_ASSERT_(expr, msg) \
-  typedef ::testing::internal::CompileAssert<(static_cast<bool>(expr))> \
-      msg[static_cast<bool>(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_
-#endif  // !GTEST_LANG_CXX11
-
-// Implementation details of GTEST_COMPILE_ASSERT_:
-//
-// (In C++11, we simply use static_assert instead of the following)
-//
-// - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1
-//   elements (and thus is invalid) when the expression is false.
-//
-// - The simpler definition
-//
-//    #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1]
-//
-//   does not work, as gcc supports variable-length arrays whose sizes
-//   are determined at run-time (this is gcc's extension and not part
-//   of the C++ standard).  As a result, gcc fails to reject the
-//   following code with the simple definition:
-//
-//     int foo;
-//     GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is
-//                                      // not a compile-time constant.
-//
-// - By using the type CompileAssert<(bool(expr))>, we ensures that
-//   expr is a compile-time constant.  (Template arguments must be
-//   determined at compile-time.)
-//
-// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
-//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written
-//
-//     CompileAssert<bool(expr)>
-//
-//   instead, these compilers will refuse to compile
-//
-//     GTEST_COMPILE_ASSERT_(5 > 0, some_message);
-//
-//   (They seem to think the ">" in "5 > 0" marks the end of the
-//   template argument list.)
-//
-// - The array size is (bool(expr) ? 1 : -1), instead of simply
-//
-//     ((expr) ? 1 : -1).
-//
-//   This is to avoid running into a bug in MS VC 7.1, which
-//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
+// The second argument to the macro must be a valid C++ identifier. If the
+// expression is false, compiler will issue an error containing this identifier.
+#define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg)
 
 // StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h.
 //
@@ -2373,6 +1110,16 @@
   enum { value = true };
 };
 
+// Same as std::is_same<>.
+template <typename T, typename U>
+struct IsSame {
+  enum { value = false };
+};
+template <typename T>
+struct IsSame<T, T> {
+  enum { value = true };
+};
+
 // Evaluates to the number of elements in 'array'.
 #define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0]))
 
@@ -2392,50 +1139,12 @@
 // returns 'condition'.
 GTEST_API_ bool IsTrue(bool condition);
 
-// Defines scoped_ptr.
-
-// This implementation of scoped_ptr is PARTIAL - it only contains
-// enough stuff to satisfy Google Test's need.
-template <typename T>
-class scoped_ptr {
- public:
-  typedef T element_type;
-
-  explicit scoped_ptr(T* p = NULL) : ptr_(p) {}
-  ~scoped_ptr() { reset(); }
-
-  T& operator*() const { return *ptr_; }
-  T* operator->() const { return ptr_; }
-  T* get() const { return ptr_; }
-
-  T* release() {
-    T* const ptr = ptr_;
-    ptr_ = NULL;
-    return ptr;
-  }
-
-  void reset(T* p = NULL) {
-    if (p != ptr_) {
-      if (IsTrue(sizeof(T) > 0)) {  // Makes sure T is a complete type.
-        delete ptr_;
-      }
-      ptr_ = p;
-    }
-  }
-
-  friend void swap(scoped_ptr& a, scoped_ptr& b) {
-    using std::swap;
-    swap(a.ptr_, b.ptr_);
-  }
-
- private:
-  T* ptr_;
-
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr);
-};
-
 // Defines RE.
 
+#if GTEST_USES_PCRE
+// if used, PCRE is injected by custom/gtest-port.h
+#elif GTEST_USES_POSIX_RE || GTEST_USES_SIMPLE_RE
+
 // A simple C++ wrapper for <regex.h>.  It uses the POSIX Extended
 // Regular Expression syntax.
 class GTEST_API_ RE {
@@ -2447,11 +1156,11 @@
   // Constructs an RE from a string.
   RE(const ::std::string& regex) { Init(regex.c_str()); }  // NOLINT
 
-#if GTEST_HAS_GLOBAL_STRING
+# if GTEST_HAS_GLOBAL_STRING
 
   RE(const ::string& regex) { Init(regex.c_str()); }  // NOLINT
 
-#endif  // GTEST_HAS_GLOBAL_STRING
+# endif  // GTEST_HAS_GLOBAL_STRING
 
   RE(const char* regex) { Init(regex); }  // NOLINT
   ~RE();
@@ -2463,9 +1172,6 @@
   // the entire str.
   // PartialMatch(str, re) returns true iff regular expression re
   // matches a substring of str (including str itself).
-  //
-  // TODO(wan@google.com): make FullMatch() and PartialMatch() work
-  // when str contains NUL characters.
   static bool FullMatch(const ::std::string& str, const RE& re) {
     return FullMatch(str.c_str(), re);
   }
@@ -2473,7 +1179,7 @@
     return PartialMatch(str.c_str(), re);
   }
 
-#if GTEST_HAS_GLOBAL_STRING
+# if GTEST_HAS_GLOBAL_STRING
 
   static bool FullMatch(const ::string& str, const RE& re) {
     return FullMatch(str.c_str(), re);
@@ -2482,34 +1188,32 @@
     return PartialMatch(str.c_str(), re);
   }
 
-#endif  // GTEST_HAS_GLOBAL_STRING
+# endif  // GTEST_HAS_GLOBAL_STRING
 
   static bool FullMatch(const char* str, const RE& re);
   static bool PartialMatch(const char* str, const RE& re);
 
  private:
   void Init(const char* regex);
-
-  // We use a const char* instead of an std::string, as Google Test used to be
-  // used where std::string is not available.  TODO(wan@google.com): change to
-  // std::string.
   const char* pattern_;
   bool is_valid_;
 
-#if GTEST_USES_POSIX_RE
+# if GTEST_USES_POSIX_RE
 
   regex_t full_regex_;     // For FullMatch().
   regex_t partial_regex_;  // For PartialMatch().
 
-#else  // GTEST_USES_SIMPLE_RE
+# else  // GTEST_USES_SIMPLE_RE
 
   const char* full_pattern_;  // For FullMatch();
 
-#endif
+# endif
 
   GTEST_DISALLOW_ASSIGN_(RE);
 };
 
+#endif  // GTEST_USES_PCRE
+
 // Formats a source file path and a line number as they would appear
 // in an error message from the compiler used to compile this code.
 GTEST_API_ ::std::string FormatFileLocation(const char* file, int line);
@@ -2558,7 +1262,7 @@
                                   __FILE__, __LINE__).GetStream()
 
 inline void LogToStderr() {}
-inline void FlushInfoLog() { fflush(NULL); }
+inline void FlushInfoLog() { fflush(nullptr); }
 
 #endif  // !defined(GTEST_LOG_)
 
@@ -2595,14 +1299,38 @@
     GTEST_LOG_(FATAL) << #posix_call << "failed with error " \
                       << gtest_error
 
-#if GTEST_HAS_STD_MOVE_
-using std::move;
-#else  // GTEST_HAS_STD_MOVE_
+// Adds reference to a type if it is not a reference type,
+// otherwise leaves it unchanged.  This is the same as
+// tr1::add_reference, which is not widely available yet.
 template <typename T>
-const T& move(const T& t) {
-  return t;
-}
-#endif  // GTEST_HAS_STD_MOVE_
+struct AddReference { typedef T& type; };  // NOLINT
+template <typename T>
+struct AddReference<T&> { typedef T& type; };  // NOLINT
+
+// A handy wrapper around AddReference that works when the argument T
+// depends on template parameters.
+#define GTEST_ADD_REFERENCE_(T) \
+    typename ::testing::internal::AddReference<T>::type
+
+// Transforms "T" into "const T&" according to standard reference collapsing
+// rules (this is only needed as a backport for C++98 compilers that do not
+// support reference collapsing). Specifically, it transforms:
+//
+//   char         ==> const char&
+//   const char   ==> const char&
+//   char&        ==> char&
+//   const char&  ==> const char&
+//
+// Note that the non-const reference will not have "const" added. This is
+// standard, and necessary so that "T" can always bind to "const T&".
+template <typename T>
+struct ConstRef { typedef const T& type; };
+template <typename T>
+struct ConstRef<T&> { typedef T& type; };
+
+// The argument T must depend on some template parameters.
+#define GTEST_REFERENCE_TO_CONST_(T) \
+  typename ::testing::internal::ConstRef<T>::type
 
 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
 //
@@ -2657,13 +1385,13 @@
   GTEST_INTENTIONAL_CONST_COND_PUSH_()
   if (false) {
   GTEST_INTENTIONAL_CONST_COND_POP_()
-    const To to = NULL;
-    ::testing::internal::ImplicitCast_<From*>(to);
+  const To to = nullptr;
+  ::testing::internal::ImplicitCast_<From*>(to);
   }
 
 #if GTEST_HAS_RTTI
   // RTTI: debug mode only!
-  GTEST_CHECK_(f == NULL || dynamic_cast<To>(f) != NULL);
+  GTEST_CHECK_(f == nullptr || dynamic_cast<To>(f) != nullptr);
 #endif
   return static_cast<To>(f);
 }
@@ -2702,10 +1430,6 @@
 GTEST_API_ std::string GetCapturedStderr();
 
 #endif  // GTEST_HAS_STREAM_REDIRECTION
-
-// Returns a path to temporary directory.
-GTEST_API_ std::string TempDir();
-
 // Returns the size (in bytes) of a file.
 GTEST_API_ size_t GetFileSize(FILE* file);
 
@@ -2713,14 +1437,18 @@
 GTEST_API_ std::string ReadEntireFile(FILE* file);
 
 // All command line arguments.
-GTEST_API_ const ::std::vector<testing::internal::string>& GetArgvs();
+GTEST_API_ std::vector<std::string> GetArgvs();
 
 #if GTEST_HAS_DEATH_TEST
 
-const ::std::vector<testing::internal::string>& GetInjectableArgvs();
-void SetInjectableArgvs(const ::std::vector<testing::internal::string>*
-                             new_argvs);
-
+std::vector<std::string> GetInjectableArgvs();
+// Deprecated: pass the args vector by value instead.
+void SetInjectableArgvs(const std::vector<std::string>* new_argvs);
+void SetInjectableArgvs(const std::vector<std::string>& new_argvs);
+#if GTEST_HAS_GLOBAL_STRING
+void SetInjectableArgvs(const std::vector< ::string>& new_argvs);
+#endif  // GTEST_HAS_GLOBAL_STRING
+void ClearInjectableArgvs();
 
 #endif  // GTEST_HAS_DEATH_TEST
 
@@ -2735,7 +1463,7 @@
     0,                  // 0 seconds.
     n * 1000L * 1000L,  // And n ms.
   };
-  nanosleep(&time, NULL);
+  nanosleep(&time, nullptr);
 }
 # endif  // GTEST_HAS_PTHREAD
 
@@ -2753,7 +1481,7 @@
 class Notification {
  public:
   Notification() : notified_(false) {
-    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
   }
   ~Notification() {
     pthread_mutex_destroy(&mutex_);
@@ -2862,7 +1590,7 @@
 // pass into pthread_create().
 extern "C" inline void* ThreadFuncWithCLinkage(void* thread) {
   static_cast<ThreadWithParamBase*>(thread)->Run();
-  return NULL;
+  return nullptr;
 }
 
 // Helper class for testing Google Test's multi-threading constructs.
@@ -2891,20 +1619,19 @@
     // The thread can be created only after all fields except thread_
     // have been initialized.
     GTEST_CHECK_POSIX_SUCCESS_(
-        pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base));
+        pthread_create(&thread_, nullptr, &ThreadFuncWithCLinkage, base));
   }
-  ~ThreadWithParam() { Join(); }
+  ~ThreadWithParam() override { Join(); }
 
   void Join() {
     if (!finished_) {
-      GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));
+      GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, nullptr));
       finished_ = true;
     }
   }
 
-  virtual void Run() {
-    if (thread_can_start_ != NULL)
-      thread_can_start_->WaitForNotification();
+  void Run() override {
+    if (thread_can_start_ != nullptr) thread_can_start_->WaitForNotification();
     func_(param_);
   }
 
@@ -2970,7 +1697,7 @@
   // Initializes owner_thread_id_ and critical_section_ in static mutexes.
   void ThreadSafeLazyInit();
 
-  // Per http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx,
+  // Per https://blogs.msdn.microsoft.com/oldnewthing/20040223-00/?p=40503,
   // we assume that 0 is an invalid value for thread IDs.
   unsigned int owner_thread_id_;
 
@@ -3198,7 +1925,7 @@
     GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory);
   };
 
-  scoped_ptr<ValueHolderFactory> default_factory_;
+  std::unique_ptr<ValueHolderFactory> default_factory_;
 
   GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
 };
@@ -3254,15 +1981,20 @@
      extern ::testing::internal::MutexBase mutex
 
 // Defines and statically (i.e. at link time) initializes a static mutex.
-#  define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
-     ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false, pthread_t() }
+// The initialization list here does not explicitly initialize each field,
+// instead relying on default initialization for the unspecified fields. In
+// particular, the owner_ field (a pthread_t) is not explicitly initialized.
+// This allows initialization to work whether pthread_t is a scalar or struct.
+// The flag -Wmissing-field-initializers must not be specified for this to work.
+#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
+  ::testing::internal::MutexBase mutex = {PTHREAD_MUTEX_INITIALIZER, false, 0}
 
 // The Mutex class can only be used for mutexes created at runtime. It
 // shares its API with MutexBase otherwise.
 class Mutex : public MutexBase {
  public:
   Mutex() {
-    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
     has_owner_ = false;
   }
   ~Mutex() {
@@ -3312,7 +2044,7 @@
 
 // Implements thread-local storage on pthreads-based systems.
 template <typename T>
-class ThreadLocal {
+class GTEST_API_ ThreadLocal {
  public:
   ThreadLocal()
       : key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {}
@@ -3360,7 +2092,7 @@
   T* GetOrCreateValue() const {
     ThreadLocalValueHolderBase* const holder =
         static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_));
-    if (holder != NULL) {
+    if (holder != nullptr) {
       return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();
     }
 
@@ -3404,7 +2136,7 @@
 
   // A key pthreads uses for looking up per-thread values.
   const pthread_key_t key_;
-  scoped_ptr<ValueHolderFactory> default_factory_;
+  std::unique_ptr<ValueHolderFactory> default_factory_;
 
   GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
 };
@@ -3444,7 +2176,7 @@
 typedef GTestMutexLock MutexLock;
 
 template <typename T>
-class ThreadLocal {
+class GTEST_API_ ThreadLocal {
  public:
   ThreadLocal() : value_() {}
   explicit ThreadLocal(const T& value) : value_(value) {}
@@ -3462,28 +2194,6 @@
 // we cannot detect it.
 GTEST_API_ size_t GetThreadCount();
 
-// Passing non-POD classes through ellipsis (...) crashes the ARM
-// compiler and generates a warning in Sun Studio.  The Nokia Symbian
-// and the IBM XL C/C++ compiler try to instantiate a copy constructor
-// for objects passed through ellipsis (...), failing for uncopyable
-// objects.  We define this to ensure that only POD is passed through
-// ellipsis on these systems.
-#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC)
-// We lose support for NULL detection where the compiler doesn't like
-// passing non-POD classes through ellipsis (...).
-# define GTEST_ELLIPSIS_NEEDS_POD_ 1
-#else
-# define GTEST_CAN_COMPARE_NULL 1
-#endif
-
-// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between
-// const T& and const T* in a function template.  These compilers
-// _can_ decide between class template specializations for T and T*,
-// so a tr1::type_traits-like is_pointer works.
-#if defined(__SYMBIAN32__) || defined(__IBMCPP__)
-# define GTEST_NEEDS_IS_POINTER_ 1
-#endif
-
 template <bool bool_value>
 struct bool_constant {
   typedef bool_constant<bool_value> type;
@@ -3494,17 +2204,18 @@
 typedef bool_constant<false> false_type;
 typedef bool_constant<true> true_type;
 
-template <typename T>
-struct is_pointer : public false_type {};
+template <typename T, typename U>
+struct is_same : public false_type {};
 
 template <typename T>
-struct is_pointer<T*> : public true_type {};
+struct is_same<T, T> : public true_type {};
 
 template <typename Iterator>
 struct IteratorTraits {
   typedef typename Iterator::value_type value_type;
 };
 
+
 template <typename T>
 struct IteratorTraits<T*> {
   typedef T value_type;
@@ -3636,7 +2347,7 @@
 
 // Functions deprecated by MSVC 8.0.
 
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* deprecated function */)
+GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
 
 inline const char* StrNCpy(char* dest, const char* src, size_t n) {
   return strncpy(dest, src, n);
@@ -3670,29 +2381,29 @@
 inline const char* StrError(int errnum) { return strerror(errnum); }
 #endif
 inline const char* GetEnv(const char* name) {
-#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE | GTEST_OS_WINDOWS_RT
+#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
   // We are on Windows CE, which has no environment variables.
   static_cast<void>(name);  // To prevent 'unused argument' warning.
-  return NULL;
+  return nullptr;
 #elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
   // Environment variables which we programmatically clear will be set to the
   // empty string rather than unset (NULL).  Handle that case.
   const char* const env = getenv(name);
-  return (env != NULL && env[0] != '\0') ? env : NULL;
+  return (env != nullptr && env[0] != '\0') ? env : nullptr;
 #else
   return getenv(name);
 #endif
 }
 
-GTEST_DISABLE_MSC_WARNINGS_POP_()
+GTEST_DISABLE_MSC_DEPRECATED_POP_()
 
 #if GTEST_OS_WINDOWS_MOBILE
 // Windows CE has no C library. The abort() function is used in
 // several places in Google Test. This implementation provides a reasonable
 // imitation of standard behaviour.
-void Abort();
+[[noreturn]] void Abort();
 #else
-inline void Abort() { abort(); }
+[[noreturn]] inline void Abort() { abort(); }
 #endif  // GTEST_OS_WINDOWS_MOBILE
 
 }  // namespace posix
@@ -3702,13 +2413,12 @@
 // MSVC-based platforms.  We map the GTEST_SNPRINTF_ macro to the appropriate
 // function in order to achieve that.  We use macro definition here because
 // snprintf is a variadic function.
-#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE
+#if _MSC_VER && !GTEST_OS_WINDOWS_MOBILE
 // MSVC 2005 and above support variadic macros.
 # define GTEST_SNPRINTF_(buffer, size, format, ...) \
      _snprintf_s(buffer, size, size, format, __VA_ARGS__)
 #elif defined(_MSC_VER)
-// Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't
-// complain about _snprintf.
+// Windows CE does not define _snprintf_s
 # define GTEST_SNPRINTF_ _snprintf
 #else
 # define GTEST_SNPRINTF_ snprintf
@@ -3800,15 +2510,15 @@
 # define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
 # define GTEST_DECLARE_int32_(name) \
     GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)
-#define GTEST_DECLARE_string_(name) \
+# define GTEST_DECLARE_string_(name) \
     GTEST_API_ extern ::std::string GTEST_FLAG(name)
 
 // Macros for defining flags.
-#define GTEST_DEFINE_bool_(name, default_val, doc) \
+# define GTEST_DEFINE_bool_(name, default_val, doc) \
     GTEST_API_ bool GTEST_FLAG(name) = (default_val)
-#define GTEST_DEFINE_int32_(name, default_val, doc) \
+# define GTEST_DEFINE_int32_(name, default_val, doc) \
     GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
-#define GTEST_DEFINE_string_(name, default_val, doc) \
+# define GTEST_DEFINE_string_(name, default_val, doc) \
     GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val)
 
 #endif  // !defined(GTEST_DECLARE_bool_)
@@ -3822,20 +2532,38 @@
 // Parses 'str' for a 32-bit signed integer.  If successful, writes the result
 // to *value and returns true; otherwise leaves *value unchanged and returns
 // false.
-// TODO(chandlerc): Find a better way to refactor flag and environment parsing
-// out of both gtest-port.cc and gtest.cc to avoid exporting this utility
-// function.
 bool ParseInt32(const Message& src_text, const char* str, Int32* value);
 
 // Parses a bool/Int32/string from the environment variable
 // corresponding to the given Google Test flag.
 bool BoolFromGTestEnv(const char* flag, bool default_val);
 GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val);
-std::string StringFromGTestEnv(const char* flag, const char* default_val);
+std::string OutputFlagAlsoCheckEnvVar();
+const char* StringFromGTestEnv(const char* flag, const char* default_val);
 
 }  // namespace internal
 }  // namespace testing
 
+#if !defined(GTEST_INTERNAL_DEPRECATED)
+
+// Internal Macro to mark an API deprecated, for googletest usage only
+// Usage: class GTEST_INTERNAL_DEPRECATED(message) MyClass or
+// GTEST_INTERNAL_DEPRECATED(message) <return_type> myFunction(); Every usage of
+// a deprecated entity will trigger a warning when compiled with
+// `-Wdeprecated-declarations` option (clang, gcc, any __GNUC__ compiler).
+// For msvc /W3 option will need to be used
+// Note that for 'other' compilers this macro evaluates to nothing to prevent
+// compilations errors.
+#if defined(_MSC_VER)
+#define GTEST_INTERNAL_DEPRECATED(message) __declspec(deprecated(message))
+#elif defined(__GNUC__)
+#define GTEST_INTERNAL_DEPRECATED(message) __attribute__((deprecated(message)))
+#else
+#define GTEST_INTERNAL_DEPRECATED(message)
+#endif
+
+#endif  // !defined(GTEST_INTERNAL_DEPRECATED)
+
 #endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
 
 #if GTEST_OS_LINUX
@@ -3857,6 +2585,7 @@
 #include <map>
 #include <set>
 #include <string>
+#include <type_traits>
 #include <vector>
 
 // Copyright 2005, Google Inc.
@@ -3887,10 +2616,9 @@
 // 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: wan@google.com (Zhanyong Wan)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
 //
 // This header file defines the Message class.
 //
@@ -3904,12 +2632,18 @@
 // to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user
 // program!
 
+// GOOGLETEST_CM0001 DO NOT DELETE
+
 #ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
 #define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
 
 #include <limits>
+#include <memory>
 
 
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
 // Ensures that there is at least one operator<< in the global namespace.
 // See Message& operator<<(...) below for why.
 void operator<<(const testing::internal::Secret&, int);
@@ -3962,14 +2696,6 @@
     *ss_ << str;
   }
 
-#if GTEST_OS_SYMBIAN
-  // Streams a value (either a pointer or not) to this object.
-  template <typename T>
-  inline Message& operator <<(const T& value) {
-    StreamHelper(typename internal::is_pointer<T>::type(), value);
-    return *this;
-  }
-#else
   // Streams a non-pointer value to this object.
   template <typename T>
   inline Message& operator <<(const T& val) {
@@ -4007,14 +2733,13 @@
   // as "(null)".
   template <typename T>
   inline Message& operator <<(T* const& pointer) {  // NOLINT
-    if (pointer == NULL) {
+    if (pointer == nullptr) {
       *ss_ << "(null)";
     } else {
       *ss_ << pointer;
     }
     return *this;
   }
-#endif  // GTEST_OS_SYMBIAN
 
   // Since the basic IO manipulators are overloaded for both narrow
   // and wide streams, we have to provide this specialized definition
@@ -4056,32 +2781,8 @@
   std::string GetString() const;
 
  private:
-
-#if GTEST_OS_SYMBIAN
-  // These are needed as the Nokia Symbian Compiler cannot decide between
-  // const T& and const T* in a function template. The Nokia compiler _can_
-  // decide between class template specializations for T and T*, so a
-  // tr1::type_traits-like is_pointer works, and we can overload on that.
-  template <typename T>
-  inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) {
-    if (pointer == NULL) {
-      *ss_ << "(null)";
-    } else {
-      *ss_ << pointer;
-    }
-  }
-  template <typename T>
-  inline void StreamHelper(internal::false_type /*is_pointer*/,
-                           const T& value) {
-    // See the comments in Message& operator <<(const T&) above for why
-    // we need this using statement.
-    using ::operator <<;
-    *ss_ << value;
-  }
-#endif  // GTEST_OS_SYMBIAN
-
   // We'll hold the text streamed to this object here.
-  const internal::scoped_ptr< ::std::stringstream> ss_;
+  const std::unique_ptr< ::std::stringstream> ss_;
 
   // We declare (but don't implement) this to prevent the compiler
   // from implementing the assignment operator.
@@ -4107,7 +2808,51 @@
 }  // namespace internal
 }  // namespace testing
 
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251
+
 #endif  // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
+// Copyright 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.
+//
+// Google Test filepath utilities
+//
+// This header file declares classes and functions used internally by
+// Google Test.  They are subject to change without notice.
+//
+// This file is #included in gtest/internal/gtest-internal.h.
+// Do not include this header file separately!
+
+// GOOGLETEST_CM0001 DO NOT DELETE
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
+
 // Copyright 2005, Google Inc.
 // All rights reserved.
 //
@@ -4137,17 +2882,17 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
-// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
 //
 // This header file declares the String class and functions used internally by
 // Google Test.  They are subject to change without notice. They should not used
 // by code external to Google Test.
 //
-// This header file is #included by <gtest/internal/gtest-internal.h>.
+// This header file is #included by gtest-internal.h.
 // It should not be #included by other files.
 
+// GOOGLETEST_CM0001 DO NOT DELETE
+
 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
 
@@ -4274,48 +3019,9 @@
 }  // namespace testing
 
 #endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
-// Copyright 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: keith.ray@gmail.com (Keith Ray)
-//
-// Google Test filepath utilities
-//
-// This header file declares classes and functions used internally by
-// Google Test.  They are subject to change without notice.
-//
-// This file is #included in <gtest/internal/gtest-internal.h>.
-// Do not include this header file separately!
 
-#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
-#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
-
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
 
 namespace testing {
 namespace internal {
@@ -4478,6 +3184,8 @@
 }  // namespace internal
 }  // namespace testing
 
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251
+
 #endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
 // This file was GENERATED by command:
 //     pump.py gtest-type-util.h.pump
@@ -4511,17 +3219,17 @@
 // 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: wan@google.com (Zhanyong Wan)
 
 // Type utilities needed for implementing typed and type-parameterized
 // tests.  This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
 //
 // Currently we support at most 50 types in a list, and at most 50
-// type-parameterized tests in one type-parameterized test case.
+// type-parameterized tests in one type-parameterized test suite.
 // Please contact googletestframework@googlegroups.com if you need
 // more.
 
+// GOOGLETEST_CM0001 DO NOT DELETE
+
 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
 
@@ -4537,6 +3245,22 @@
 namespace testing {
 namespace internal {
 
+// Canonicalizes a given name with respect to the Standard C++ Library.
+// This handles removing the inline namespace within `std` that is
+// used by various standard libraries (e.g., `std::__1`).  Names outside
+// of namespace std are returned unmodified.
+inline std::string CanonicalizeForStdLibVersioning(std::string s) {
+  static const char prefix[] = "std::__";
+  if (s.compare(0, strlen(prefix), prefix) == 0) {
+    std::string::size_type end = s.find("::", strlen(prefix));
+    if (end != s.npos) {
+      // Erase everything between the initial `std` and the second `::`.
+      s.erase(strlen("std"), end - strlen("std"));
+    }
+  }
+  return s;
+}
+
 // GetTypeName<T>() returns a human-readable name of type T.
 // NB: This function is also used in Google Mock, so don't move it inside of
 // the typed-test-only section below.
@@ -4552,10 +3276,10 @@
 #   if GTEST_HAS_CXXABI_H_
   using abi::__cxa_demangle;
 #   endif  // GTEST_HAS_CXXABI_H_
-  char* const readable_name = __cxa_demangle(name, 0, 0, &status);
+  char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
   const std::string name_str(status == 0 ? readable_name : name);
   free(readable_name);
-  return name_str;
+  return CanonicalizeForStdLibVersioning(name_str);
 #  else
   return name;
 #  endif  // GTEST_HAS_CXXABI_H_ || __HP_aCC
@@ -7775,8 +6499,8 @@
 };
 
 // The TypeList template makes it possible to use either a single type
-// or a Types<...> list in TYPED_TEST_CASE() and
-// INSTANTIATE_TYPED_TEST_CASE_P().
+// or a Types<...> list in TYPED_TEST_SUITE() and
+// INSTANTIATE_TYPED_TEST_SUITE_P().
 
 template <typename T>
 struct TypeList {
@@ -7821,6 +6545,9 @@
 #define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
 #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar
 
+// Stringifies its argument.
+#define GTEST_STRINGIFY_(name) #name
+
 class ProtocolMessage;
 namespace proto2 { class Message; }
 
@@ -7833,7 +6560,7 @@
 class Test;                            // Represents a test.
 class TestInfo;                        // Information about a test.
 class TestPartResult;                  // Result of a test part.
-class UnitTest;                        // A collection of test cases.
+class UnitTest;                        // A collection of test suites.
 
 template <typename T>
 ::std::string PrintToString(const T& value);
@@ -7841,7 +6568,6 @@
 namespace internal {
 
 struct TraceInfo;                      // Information about a trace point.
-class ScopedTrace;                     // Implements scoped trace.
 class TestInfoImpl;                    // Opaque implementation of TestInfo
 class UnitTestImpl;                    // Opaque implementation of UnitTest
 
@@ -7849,12 +6575,35 @@
 // stack trace.
 GTEST_API_ extern const char kStackTraceMarker[];
 
+// An IgnoredValue object can be implicitly constructed from ANY value.
+class IgnoredValue {
+  struct Sink {};
+ public:
+  // This constructor template allows any value to be implicitly
+  // converted to IgnoredValue.  The object has no data member and
+  // doesn't try to remember anything about the argument.  We
+  // deliberately omit the 'explicit' keyword in order to allow the
+  // conversion to be implicit.
+  // Disable the conversion if T already has a magical conversion operator.
+  // Otherwise we get ambiguity.
+  template <typename T,
+            typename std::enable_if<!std::is_convertible<T, Sink>::value,
+                                    int>::type = 0>
+  IgnoredValue(const T& /* ignored */) {}  // NOLINT(runtime/explicit)
+};
+
+// The only type that should be convertible to Secret* is nullptr.
+// The other null pointer constants are not of a type that is convertible to
+// Secret*. Only the literal with the right value is.
+template <typename T>
+using TypeIsValidNullptrConstant = std::integral_constant<
+    bool, std::is_same<typename std::decay<T>::type, std::nullptr_t>::value ||
+              !std::is_convertible<T, Secret*>::value>;
+
 // Two overloaded helpers for checking at compile time whether an
 // expression is a null pointer literal (i.e. NULL or any 0-valued
-// compile-time integral constant).  Their return values have
-// different sizes, so we can use sizeof() to test which version is
-// picked by the compiler.  These helpers have no implementations, as
-// we only need their signatures.
+// compile-time integral constant).  These helpers have no
+// implementations, as we only need their signatures.
 //
 // Given IsNullLiteralHelper(x), the compiler will pick the first
 // version if x can be implicitly converted to Secret*, and pick the
@@ -7863,20 +6612,16 @@
 // a null pointer literal.  Therefore, we know that x is a null
 // pointer literal if and only if the first version is picked by the
 // compiler.
-char IsNullLiteralHelper(Secret* p);
-char (&IsNullLiteralHelper(...))[2];  // NOLINT
+std::true_type IsNullLiteralHelper(Secret*, std::true_type);
+std::false_type IsNullLiteralHelper(IgnoredValue, std::false_type);
+std::false_type IsNullLiteralHelper(IgnoredValue, std::true_type);
 
-// A compile-time bool constant that is true if and only if x is a
-// null pointer literal (i.e. NULL or any 0-valued compile-time
-// integral constant).
-#ifdef GTEST_ELLIPSIS_NEEDS_POD_
-// We lose support for NULL detection where the compiler doesn't like
-// passing non-POD classes through ellipsis (...).
-# define GTEST_IS_NULL_LITERAL_(x) false
-#else
-# define GTEST_IS_NULL_LITERAL_(x) \
-    (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1)
-#endif  // GTEST_ELLIPSIS_NEEDS_POD_
+// A compile-time bool constant that is true if and only if x is a null pointer
+// literal (i.e. nullptr, NULL or any 0-valued compile-time integral constant).
+#define GTEST_IS_NULL_LITERAL_(x)                    \
+  decltype(::testing::internal::IsNullLiteralHelper( \
+      x,                                             \
+      ::testing::internal::TypeIsValidNullptrConstant<decltype(x)>()))::value
 
 // Appends the user-supplied message to the Google-Test-generated message.
 GTEST_API_ std::string AppendUserMessage(
@@ -7884,6 +6629,9 @@
 
 #if GTEST_HAS_EXCEPTIONS
 
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4275 \
+/* an exported class was derived from a class that was not exported */)
+
 // This exception is thrown by (and only by) a failed Google Test
 // assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions
 // are enabled).  We derive it from std::runtime_error, which is for
@@ -7895,32 +6643,15 @@
   explicit GoogleTestFailureException(const TestPartResult& failure);
 };
 
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4275
+
 #endif  // GTEST_HAS_EXCEPTIONS
 
-// A helper class for creating scoped traces in user programs.
-class GTEST_API_ ScopedTrace {
- public:
-  // The c'tor pushes the given source file location and message onto
-  // a trace stack maintained by Google Test.
-  ScopedTrace(const char* file, int line, const Message& message);
-
-  // The d'tor pops the info pushed by the c'tor.
-  //
-  // Note that the d'tor is not virtual in order to be efficient.
-  // Don't inherit from ScopedTrace!
-  ~ScopedTrace();
-
- private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace);
-} GTEST_ATTRIBUTE_UNUSED_;  // A ScopedTrace object does its job in its
-                            // c'tor and d'tor.  Therefore it doesn't
-                            // need to be used otherwise.
-
 namespace edit_distance {
 // Returns the optimal edits to go from 'left' to 'right'.
 // All edits cost the same, with replace having lower priority than
 // add/remove.
-// Simple implementation of the Wagner–Fischer algorithm.
+// Simple implementation of the Wagner-Fischer algorithm.
 // See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm
 enum EditType { kMatch, kAdd, kRemove, kReplace };
 GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
@@ -8166,7 +6897,7 @@
 typedef FloatingPoint<double> Double;
 
 // In order to catch the mistake of putting tests that use different
-// test fixture classes in the same test case, we need to assign
+// test fixture classes in the same test suite, we need to assign
 // unique IDs to fixture classes and compare them.  The TypeId type is
 // used to hold such IDs.  The user should treat TypeId as an opaque
 // type: the only operation allowed on TypeId values is to compare
@@ -8226,7 +6957,7 @@
 template <class TestClass>
 class TestFactoryImpl : public TestFactoryBase {
  public:
-  virtual Test* CreateTest() { return new TestClass; }
+  Test* CreateTest() override { return new TestClass; }
 };
 
 #if GTEST_OS_WINDOWS
@@ -8242,23 +6973,72 @@
 
 #endif  // GTEST_OS_WINDOWS
 
-// Types of SetUpTestCase() and TearDownTestCase() functions.
-typedef void (*SetUpTestCaseFunc)();
-typedef void (*TearDownTestCaseFunc)();
+// Types of SetUpTestSuite() and TearDownTestSuite() functions.
+using SetUpTestSuiteFunc = void (*)();
+using TearDownTestSuiteFunc = void (*)();
 
 struct CodeLocation {
-  CodeLocation(const string& a_file, int a_line) : file(a_file), line(a_line) {}
+  CodeLocation(const std::string& a_file, int a_line)
+      : file(a_file), line(a_line) {}
 
-  string file;
+  std::string file;
   int line;
 };
 
+//  Helper to identify which setup function for TestCase / TestSuite to call.
+//  Only one function is allowed, either TestCase or TestSute but not both.
+
+// Utility functions to help SuiteApiResolver
+using SetUpTearDownSuiteFuncType = void (*)();
+
+inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull(
+    SetUpTearDownSuiteFuncType a, SetUpTearDownSuiteFuncType def) {
+  return a == def ? nullptr : a;
+}
+
+template <typename T>
+//  Note that SuiteApiResolver inherits from T because
+//  SetUpTestSuite()/TearDownTestSuite() could be protected. Ths way
+//  SuiteApiResolver can access them.
+struct SuiteApiResolver : T {
+  // testing::Test is only forward declared at this point. So we make it a
+  // dependend class for the compiler to be OK with it.
+  using Test =
+      typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type;
+
+  static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite() {
+    SetUpTearDownSuiteFuncType test_case_fp =
+        GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase);
+    SetUpTearDownSuiteFuncType test_suite_fp =
+        GetNotDefaultOrNull(&T::SetUpTestSuite, &Test::SetUpTestSuite);
+
+    GTEST_CHECK_(!test_case_fp || !test_suite_fp)
+        << "Test can not provide both SetUpTestSuite and SetUpTestCase, please "
+           "make sure there is only one present ";
+
+    return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
+  }
+
+  static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite() {
+    SetUpTearDownSuiteFuncType test_case_fp =
+        GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase);
+    SetUpTearDownSuiteFuncType test_suite_fp =
+        GetNotDefaultOrNull(&T::TearDownTestSuite, &Test::TearDownTestSuite);
+
+    GTEST_CHECK_(!test_case_fp || !test_suite_fp)
+        << "Test can not provide both TearDownTestSuite and TearDownTestCase,"
+           " please make sure there is only one present ";
+
+    return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
+  }
+};
+
 // Creates a new TestInfo object and registers it with Google Test;
 // returns the created object.
 //
 // Arguments:
 //
-//   test_case_name:   name of the test case
+//   test_suite_name:   name of the test suite
 //   name:             name of the test
 //   type_param        the name of the test's type parameter, or NULL if
 //                     this is not a typed or a type-parameterized test.
@@ -8266,21 +7046,16 @@
 //                     or NULL if this is not a type-parameterized test.
 //   code_location:    code location where the test is defined
 //   fixture_class_id: ID of the test fixture class
-//   set_up_tc:        pointer to the function that sets up the test case
-//   tear_down_tc:     pointer to the function that tears down the test case
+//   set_up_tc:        pointer to the function that sets up the test suite
+//   tear_down_tc:     pointer to the function that tears down the test suite
 //   factory:          pointer to the factory that creates a test object.
 //                     The newly created TestInfo instance will assume
 //                     ownership of the factory object.
 GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
-    const char* test_case_name,
-    const char* name,
-    const char* type_param,
-    const char* value_param,
-    CodeLocation code_location,
-    TypeId fixture_class_id,
-    SetUpTestCaseFunc set_up_tc,
-    TearDownTestCaseFunc tear_down_tc,
-    TestFactoryBase* factory);
+    const char* test_suite_name, const char* name, const char* type_param,
+    const char* value_param, CodeLocation code_location,
+    TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
+    TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);
 
 // If *pstr starts with the given prefix, modifies *pstr to be right
 // past the prefix and returns true; otherwise leaves *pstr unchanged
@@ -8289,19 +7064,23 @@
 
 #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
 
-// State of the definition of a type-parameterized test case.
-class GTEST_API_ TypedTestCasePState {
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
+// State of the definition of a type-parameterized test suite.
+class GTEST_API_ TypedTestSuitePState {
  public:
-  TypedTestCasePState() : registered_(false) {}
+  TypedTestSuitePState() : registered_(false) {}
 
   // Adds the given test name to defined_test_names_ and return true
-  // if the test case hasn't been registered; otherwise aborts the
+  // if the test suite hasn't been registered; otherwise aborts the
   // program.
   bool AddTestName(const char* file, int line, const char* case_name,
                    const char* test_name) {
     if (registered_) {
-      fprintf(stderr, "%s Test %s must be defined before "
-              "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n",
+      fprintf(stderr,
+              "%s Test %s must be defined before "
+              "REGISTER_TYPED_TEST_SUITE_P(%s, ...).\n",
               FormatFileLocation(file, line).c_str(), test_name, case_name);
       fflush(stderr);
       posix::Abort();
@@ -8334,12 +7113,19 @@
   RegisteredTestsMap registered_tests_;
 };
 
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+using TypedTestCasePState = TypedTestSuitePState;
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251
+
 // Skips to the first non-space char after the first comma in 'str';
 // returns NULL if no comma is found in 'str'.
 inline const char* SkipComma(const char* str) {
   const char* comma = strchr(str, ',');
-  if (comma == NULL) {
-    return NULL;
+  if (comma == nullptr) {
+    return nullptr;
   }
   while (IsSpace(*(++comma))) {}
   return comma;
@@ -8349,7 +7135,7 @@
 // the entire string if it contains no comma.
 inline std::string GetPrefixUntilComma(const char* str) {
   const char* comma = strchr(str, ',');
-  return comma == NULL ? str : std::string(str, comma);
+  return comma == nullptr ? str : std::string(str, comma);
 }
 
 // Splits a given string on a given delimiter, populating a given
@@ -8357,6 +7143,37 @@
 void SplitString(const ::std::string& str, char delimiter,
                  ::std::vector< ::std::string>* dest);
 
+// The default argument to the template below for the case when the user does
+// not provide a name generator.
+struct DefaultNameGenerator {
+  template <typename T>
+  static std::string GetName(int i) {
+    return StreamableToString(i);
+  }
+};
+
+template <typename Provided = DefaultNameGenerator>
+struct NameGeneratorSelector {
+  typedef Provided type;
+};
+
+template <typename NameGenerator>
+void GenerateNamesRecursively(Types0, std::vector<std::string>*, int) {}
+
+template <typename NameGenerator, typename Types>
+void GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) {
+  result->push_back(NameGenerator::template GetName<typename Types::Head>(i));
+  GenerateNamesRecursively<NameGenerator>(typename Types::Tail(), result,
+                                          i + 1);
+}
+
+template <typename NameGenerator, typename Types>
+std::vector<std::string> GenerateNames() {
+  std::vector<std::string> result;
+  GenerateNamesRecursively<NameGenerator>(Types(), &result, 0);
+  return result;
+}
+
 // TypeParameterizedTest<Fixture, TestSel, Types>::Register()
 // registers a list of type-parameterized tests with Google Test.  The
 // return value is insignificant - we just need to return something
@@ -8368,13 +7185,13 @@
 class TypeParameterizedTest {
  public:
   // 'index' is the index of the test in the type list 'Types'
-  // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
+  // specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
   // Types).  Valid values for 'index' are [0, N - 1] where N is the
   // length of Types.
-  static bool Register(const char* prefix,
-                       CodeLocation code_location,
-                       const char* case_name, const char* test_names,
-                       int index) {
+  static bool Register(const char* prefix, const CodeLocation& code_location,
+                       const char* case_name, const char* test_names, int index,
+                       const std::vector<std::string>& type_names =
+                           GenerateNames<DefaultNameGenerator, Types>()) {
     typedef typename Types::Head Type;
     typedef Fixture<Type> FixtureClass;
     typedef typename GTEST_BIND_(TestSel, Type) TestClass;
@@ -8382,20 +7199,25 @@
     // First, registers the first type-parameterized test in the type
     // list.
     MakeAndRegisterTestInfo(
-        (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/"
-         + StreamableToString(index)).c_str(),
+        (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
+         "/" + type_names[index])
+            .c_str(),
         StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
         GetTypeName<Type>().c_str(),
-        NULL,  // No value parameter.
-        code_location,
-        GetTypeId<FixtureClass>(),
-        TestClass::SetUpTestCase,
-        TestClass::TearDownTestCase,
+        nullptr,  // No value parameter.
+        code_location, GetTypeId<FixtureClass>(),
+        SuiteApiResolver<TestClass>::GetSetUpCaseOrSuite(),
+        SuiteApiResolver<TestClass>::GetTearDownCaseOrSuite(),
         new TestFactoryImpl<TestClass>);
 
     // Next, recurses (at compile time) with the tail of the type list.
-    return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>
-        ::Register(prefix, code_location, case_name, test_names, index + 1);
+    return TypeParameterizedTest<Fixture, TestSel,
+                                 typename Types::Tail>::Register(prefix,
+                                                                 code_location,
+                                                                 case_name,
+                                                                 test_names,
+                                                                 index + 1,
+                                                                 type_names);
   }
 };
 
@@ -8403,23 +7225,27 @@
 template <GTEST_TEMPLATE_ Fixture, class TestSel>
 class TypeParameterizedTest<Fixture, TestSel, Types0> {
  public:
-  static bool Register(const char* /*prefix*/, CodeLocation,
+  static bool Register(const char* /*prefix*/, const CodeLocation&,
                        const char* /*case_name*/, const char* /*test_names*/,
-                       int /*index*/) {
+                       int /*index*/,
+                       const std::vector<std::string>& =
+                           std::vector<std::string>() /*type_names*/) {
     return true;
   }
 };
 
-// TypeParameterizedTestCase<Fixture, Tests, Types>::Register()
+// TypeParameterizedTestSuite<Fixture, Tests, Types>::Register()
 // registers *all combinations* of 'Tests' and 'Types' with Google
 // Test.  The return value is insignificant - we just need to return
 // something such that we can call this function in a namespace scope.
 template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
-class TypeParameterizedTestCase {
+class TypeParameterizedTestSuite {
  public:
   static bool Register(const char* prefix, CodeLocation code_location,
-                       const TypedTestCasePState* state,
-                       const char* case_name, const char* test_names) {
+                       const TypedTestSuitePState* state, const char* case_name,
+                       const char* test_names,
+                       const std::vector<std::string>& type_names =
+                           GenerateNames<DefaultNameGenerator, Types>()) {
     std::string test_name = StripTrailingSpaces(
         GetPrefixUntilComma(test_names));
     if (!state->TestExists(test_name)) {
@@ -8436,22 +7262,26 @@
 
     // First, register the first test in 'Test' for each type in 'Types'.
     TypeParameterizedTest<Fixture, Head, Types>::Register(
-        prefix, test_location, case_name, test_names, 0);
+        prefix, test_location, case_name, test_names, 0, type_names);
 
     // Next, recurses (at compile time) with the tail of the test list.
-    return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>
-        ::Register(prefix, code_location, state,
-                   case_name, SkipComma(test_names));
+    return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
+                                      Types>::Register(prefix, code_location,
+                                                       state, case_name,
+                                                       SkipComma(test_names),
+                                                       type_names);
   }
 };
 
 // The base case for the compile time recursion.
 template <GTEST_TEMPLATE_ Fixture, typename Types>
-class TypeParameterizedTestCase<Fixture, Templates0, Types> {
+class TypeParameterizedTestSuite<Fixture, Templates0, Types> {
  public:
-  static bool Register(const char* /*prefix*/, CodeLocation,
-                       const TypedTestCasePState* /*state*/,
-                       const char* /*case_name*/, const char* /*test_names*/) {
+  static bool Register(const char* /*prefix*/, const CodeLocation&,
+                       const TypedTestSuitePState* /*state*/,
+                       const char* /*case_name*/, const char* /*test_names*/,
+                       const std::vector<std::string>& =
+                           std::vector<std::string>() /*type_names*/) {
     return true;
   }
 };
@@ -8549,16 +7379,6 @@
   typedef typename RemoveConst<T>::type type[N];
 };
 
-#if defined(_MSC_VER) && _MSC_VER < 1400
-// This is the only specialization that allows VC++ 7.1 to remove const in
-// 'const int[3] and 'const int[3][4]'.  However, it causes trouble with GCC
-// and thus needs to be conditionally compiled.
-template <typename T, size_t N>
-struct RemoveConst<T[N]> {
-  typedef typename RemoveConst<T>::type type[N];
-};
-#endif
-
 // A handy wrapper around RemoveConst that works when the argument
 // T depends on template parameters.
 #define GTEST_REMOVE_CONST_(T) \
@@ -8568,87 +7388,14 @@
 #define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
     GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T))
 
-// Adds reference to a type if it is not a reference type,
-// otherwise leaves it unchanged.  This is the same as
-// tr1::add_reference, which is not widely available yet.
-template <typename T>
-struct AddReference { typedef T& type; };  // NOLINT
-template <typename T>
-struct AddReference<T&> { typedef T& type; };  // NOLINT
-
-// A handy wrapper around AddReference that works when the argument T
-// depends on template parameters.
-#define GTEST_ADD_REFERENCE_(T) \
-    typename ::testing::internal::AddReference<T>::type
-
-// Adds a reference to const on top of T as necessary.  For example,
-// it transforms
-//
-//   char         ==> const char&
-//   const char   ==> const char&
-//   char&        ==> const char&
-//   const char&  ==> const char&
-//
-// The argument T must depend on some template parameters.
-#define GTEST_REFERENCE_TO_CONST_(T) \
-    GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T))
-
-// ImplicitlyConvertible<From, To>::value is a compile-time bool
-// constant that's true iff type From can be implicitly converted to
-// type To.
-template <typename From, typename To>
-class ImplicitlyConvertible {
- private:
-  // We need the following helper functions only for their types.
-  // They have no implementations.
-
-  // MakeFrom() is an expression whose type is From.  We cannot simply
-  // use From(), as the type From may not have a public default
-  // constructor.
-  static typename AddReference<From>::type MakeFrom();
-
-  // These two functions are overloaded.  Given an expression
-  // Helper(x), the compiler will pick the first version if x can be
-  // implicitly converted to type To; otherwise it will pick the
-  // second version.
-  //
-  // The first version returns a value of size 1, and the second
-  // version returns a value of size 2.  Therefore, by checking the
-  // size of Helper(x), which can be done at compile time, we can tell
-  // which version of Helper() is used, and hence whether x can be
-  // implicitly converted to type To.
-  static char Helper(To);
-  static char (&Helper(...))[2];  // NOLINT
-
-  // We have to put the 'public' section after the 'private' section,
-  // or MSVC refuses to compile the code.
- public:
-#if defined(__BORLANDC__)
-  // C++Builder cannot use member overload resolution during template
-  // instantiation.  The simplest workaround is to use its C++0x type traits
-  // functions (C++Builder 2009 and above only).
-  static const bool value = __is_convertible(From, To);
-#else
-  // MSVC warns about implicitly converting from double to int for
-  // possible loss of data, so we need to temporarily disable the
-  // warning.
-  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244)
-  static const bool value =
-      sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
-  GTEST_DISABLE_MSC_WARNINGS_POP_()
-#endif  // __BORLANDC__
-};
-template <typename From, typename To>
-const bool ImplicitlyConvertible<From, To>::value;
-
 // IsAProtocolMessage<T>::value is a compile-time bool constant that's
 // true iff T is type ProtocolMessage, proto2::Message, or a subclass
 // of those.
 template <typename T>
 struct IsAProtocolMessage
     : public bool_constant<
-  ImplicitlyConvertible<const T*, const ::ProtocolMessage*>::value ||
-  ImplicitlyConvertible<const T*, const ::proto2::Message*>::value> {
+  std::is_convertible<const T*, const ::ProtocolMessage*>::value ||
+  std::is_convertible<const T*, const ::proto2::Message*>::value> {
 };
 
 // When the compiler sees expression IsContainerTest<C>(0), if C is an
@@ -8662,8 +7409,11 @@
 // a container class by checking the type of IsContainerTest<C>(0).
 // The value of the expression is insignificant.
 //
-// Note that we look for both C::iterator and C::const_iterator.  The
-// reason is that C++ injects the name of a class as a member of the
+// In C++11 mode we check the existence of a const_iterator and that an
+// iterator is properly implemented for the container.
+//
+// For pre-C++11 that we look for both C::iterator and C::const_iterator.
+// The reason is that C++ injects the name of a class as a member of the
 // class itself (e.g. you can refer to class iterator as either
 // 'iterator' or 'iterator::iterator').  If we look for C::iterator
 // only, for example, we would mistakenly think that a class named
@@ -8673,10 +7423,13 @@
 // IsContainerTest(typename C::const_iterator*) and
 // IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++.
 typedef int IsContainer;
-template <class C>
-IsContainer IsContainerTest(int /* dummy */,
-                            typename C::iterator* /* it */ = NULL,
-                            typename C::const_iterator* /* const_it */ = NULL) {
+template <class C,
+          class Iterator = decltype(::std::declval<const C&>().begin()),
+          class = decltype(::std::declval<const C&>().end()),
+          class = decltype(++::std::declval<Iterator&>()),
+          class = decltype(*::std::declval<Iterator>()),
+          class = typename C::const_iterator>
+IsContainer IsContainerTest(int /* dummy */) {
   return 0;
 }
 
@@ -8684,6 +7437,56 @@
 template <class C>
 IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; }
 
+// Trait to detect whether a type T is a hash table.
+// The heuristic used is that the type contains an inner type `hasher` and does
+// not contain an inner type `reverse_iterator`.
+// If the container is iterable in reverse, then order might actually matter.
+template <typename T>
+struct IsHashTable {
+ private:
+  template <typename U>
+  static char test(typename U::hasher*, typename U::reverse_iterator*);
+  template <typename U>
+  static int test(typename U::hasher*, ...);
+  template <typename U>
+  static char test(...);
+
+ public:
+  static const bool value = sizeof(test<T>(nullptr, nullptr)) == sizeof(int);
+};
+
+template <typename T>
+const bool IsHashTable<T>::value;
+
+template <typename C,
+          bool = sizeof(IsContainerTest<C>(0)) == sizeof(IsContainer)>
+struct IsRecursiveContainerImpl;
+
+template <typename C>
+struct IsRecursiveContainerImpl<C, false> : public false_type {};
+
+// Since the IsRecursiveContainerImpl depends on the IsContainerTest we need to
+// obey the same inconsistencies as the IsContainerTest, namely check if
+// something is a container is relying on only const_iterator in C++11 and
+// is relying on both const_iterator and iterator otherwise
+template <typename C>
+struct IsRecursiveContainerImpl<C, true> {
+  using value_type = decltype(*std::declval<typename C::const_iterator>());
+  using type =
+      is_same<typename std::remove_const<
+                  typename std::remove_reference<value_type>::type>::type,
+              C>;
+};
+
+// IsRecursiveContainer<Type> is a unary compile-time predicate that
+// evaluates whether C is a recursive container type. A recursive container
+// type is a container type whose value_type is equal to the container type
+// itself. An example for a recursive container type is
+// boost::filesystem::path, whose iterator has a value_type that is equal to
+// boost::filesystem::path.
+template <typename C>
+struct IsRecursiveContainer : public IsRecursiveContainerImpl<C>::type {};
+
 // EnableIf<condition>::type is void when 'Cond' is true, and
 // undefined when 'Cond' is false.  To use SFINAE to make a function
 // overload only apply when a particular expression is true, add
@@ -8815,7 +7618,7 @@
  private:
   enum {
     kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper<
-        Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value,
+        Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value
   };
 
   // Initializes this object with a copy of the input.
@@ -8841,6 +7644,139 @@
   GTEST_DISALLOW_ASSIGN_(NativeArray);
 };
 
+// Backport of std::index_sequence.
+template <size_t... Is>
+struct IndexSequence {
+  using type = IndexSequence;
+};
+
+// Double the IndexSequence, and one if plus_one is true.
+template <bool plus_one, typename T, size_t sizeofT>
+struct DoubleSequence;
+template <size_t... I, size_t sizeofT>
+struct DoubleSequence<true, IndexSequence<I...>, sizeofT> {
+  using type = IndexSequence<I..., (sizeofT + I)..., 2 * sizeofT>;
+};
+template <size_t... I, size_t sizeofT>
+struct DoubleSequence<false, IndexSequence<I...>, sizeofT> {
+  using type = IndexSequence<I..., (sizeofT + I)...>;
+};
+
+// Backport of std::make_index_sequence.
+// It uses O(ln(N)) instantiation depth.
+template <size_t N>
+struct MakeIndexSequence
+    : DoubleSequence<N % 2 == 1, typename MakeIndexSequence<N / 2>::type,
+                     N / 2>::type {};
+
+template <>
+struct MakeIndexSequence<0> : IndexSequence<> {};
+
+// FIXME: This implementation of ElemFromList is O(1) in instantiation depth,
+// but it is O(N^2) in total instantiations. Not sure if this is the best
+// tradeoff, as it will make it somewhat slow to compile.
+template <typename T, size_t, size_t>
+struct ElemFromListImpl {};
+
+template <typename T, size_t I>
+struct ElemFromListImpl<T, I, I> {
+  using type = T;
+};
+
+// Get the Nth element from T...
+// It uses O(1) instantiation depth.
+template <size_t N, typename I, typename... T>
+struct ElemFromList;
+
+template <size_t N, size_t... I, typename... T>
+struct ElemFromList<N, IndexSequence<I...>, T...>
+    : ElemFromListImpl<T, N, I>... {};
+
+template <typename... T>
+class FlatTuple;
+
+template <typename Derived, size_t I>
+struct FlatTupleElemBase;
+
+template <typename... T, size_t I>
+struct FlatTupleElemBase<FlatTuple<T...>, I> {
+  using value_type =
+      typename ElemFromList<I, typename MakeIndexSequence<sizeof...(T)>::type,
+                            T...>::type;
+  FlatTupleElemBase() = default;
+  explicit FlatTupleElemBase(value_type t) : value(std::move(t)) {}
+  value_type value;
+};
+
+template <typename Derived, typename Idx>
+struct FlatTupleBase;
+
+template <size_t... Idx, typename... T>
+struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
+    : FlatTupleElemBase<FlatTuple<T...>, Idx>... {
+  using Indices = IndexSequence<Idx...>;
+  FlatTupleBase() = default;
+  explicit FlatTupleBase(T... t)
+      : FlatTupleElemBase<FlatTuple<T...>, Idx>(std::move(t))... {}
+};
+
+// Analog to std::tuple but with different tradeoffs.
+// This class minimizes the template instantiation depth, thus allowing more
+// elements that std::tuple would. std::tuple has been seen to require an
+// instantiation depth of more than 10x the number of elements in some
+// implementations.
+// FlatTuple and ElemFromList are not recursive and have a fixed depth
+// regardless of T...
+// MakeIndexSequence, on the other hand, it is recursive but with an
+// instantiation depth of O(ln(N)).
+template <typename... T>
+class FlatTuple
+    : private FlatTupleBase<FlatTuple<T...>,
+                            typename MakeIndexSequence<sizeof...(T)>::type> {
+  using Indices = typename FlatTuple::FlatTupleBase::Indices;
+
+ public:
+  FlatTuple() = default;
+  explicit FlatTuple(T... t) : FlatTuple::FlatTupleBase(std::move(t)...) {}
+
+  template <size_t I>
+  const typename ElemFromList<I, Indices, T...>::type& Get() const {
+    return static_cast<const FlatTupleElemBase<FlatTuple, I>*>(this)->value;
+  }
+
+  template <size_t I>
+  typename ElemFromList<I, Indices, T...>::type& Get() {
+    return static_cast<FlatTupleElemBase<FlatTuple, I>*>(this)->value;
+  }
+};
+
+// Utility functions to be called with static_assert to induce deprecation
+// warnings.
+GTEST_INTERNAL_DEPRECATED(
+    "INSTANTIATE_TEST_CASE_P is deprecated, please use "
+    "INSTANTIATE_TEST_SUITE_P")
+constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; }
+
+GTEST_INTERNAL_DEPRECATED(
+    "TYPED_TEST_CASE_P is deprecated, please use "
+    "TYPED_TEST_SUITE_P")
+constexpr bool TypedTestCase_P_IsDeprecated() { return true; }
+
+GTEST_INTERNAL_DEPRECATED(
+    "TYPED_TEST_CASE is deprecated, please use "
+    "TYPED_TEST_SUITE")
+constexpr bool TypedTestCaseIsDeprecated() { return true; }
+
+GTEST_INTERNAL_DEPRECATED(
+    "REGISTER_TYPED_TEST_CASE_P is deprecated, please use "
+    "REGISTER_TYPED_TEST_SUITE_P")
+constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }
+
+GTEST_INTERNAL_DEPRECATED(
+    "INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use "
+    "INSTANTIATE_TYPED_TEST_SUITE_P")
+constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
+
 }  // namespace internal
 }  // namespace testing
 
@@ -8860,7 +7796,10 @@
 #define GTEST_SUCCESS_(message) \
   GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)
 
-// Suppresses MSVC warnings 4072 (unreachable code) for the code following
+#define GTEST_SKIP_(message) \
+  return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSkip)
+
+// Suppress MSVC warning 4072 (unreachable code) for the code following
 // statement if it returns or throws (or doesn't return or throw in some
 // situations).
 #define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
@@ -8952,35 +7891,37 @@
            "  Actual: it does.")
 
 // Expands to the name of the class that implements the given test.
-#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
-  test_case_name##_##test_name##_Test
+#define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
+  test_suite_name##_##test_name##_Test
 
 // Helper macro for defining tests.
-#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
-class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
- public:\
-  GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
- private:\
-  virtual void TestBody();\
-  static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(\
-      GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
-};\
-\
-::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
-  ::test_info_ =\
-    ::testing::internal::MakeAndRegisterTestInfo(\
-        #test_case_name, #test_name, NULL, NULL, \
-        ::testing::internal::CodeLocation(__FILE__, __LINE__), \
-        (parent_id), \
-        parent_class::SetUpTestCase, \
-        parent_class::TearDownTestCase, \
-        new ::testing::internal::TestFactoryImpl<\
-            GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
-void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
+#define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id)      \
+  class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)                    \
+      : public parent_class {                                                 \
+   public:                                                                    \
+    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {}                   \
+                                                                              \
+   private:                                                                   \
+    virtual void TestBody();                                                  \
+    static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;     \
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name,   \
+                                                           test_name));       \
+  };                                                                          \
+                                                                              \
+  ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name,          \
+                                                    test_name)::test_info_ =  \
+      ::testing::internal::MakeAndRegisterTestInfo(                           \
+          #test_suite_name, #test_name, nullptr, nullptr,                     \
+          ::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \
+          ::testing::internal::SuiteApiResolver<                              \
+              parent_class>::GetSetUpCaseOrSuite(),                           \
+          ::testing::internal::SuiteApiResolver<                              \
+              parent_class>::GetTearDownCaseOrSuite(),                        \
+          new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_(    \
+              test_suite_name, test_name)>);                                  \
+  void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
 
 #endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
-
 // Copyright 2005, Google Inc.
 // All rights reserved.
 //
@@ -9009,14 +7950,14 @@
 // 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: wan@google.com (Zhanyong Wan)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
 //
 // This header file defines the public API for death tests.  It is
 // #included by gtest.h so a user doesn't need to include this
 // directly.
+// GOOGLETEST_CM0001 DO NOT DELETE
 
 #ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
 #define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
@@ -9050,1025 +7991,15 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
-// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
 //
 // This header file defines internal utilities needed for implementing
 // death tests.  They are subject to change without notice.
+// GOOGLETEST_CM0001 DO NOT DELETE
 
 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
 
-
-#include <stdio.h>
-
-namespace testing {
-namespace internal {
-
-GTEST_DECLARE_string_(internal_run_death_test);
-
-// Names of the flags (needed for parsing Google Test flags).
-const char kDeathTestStyleFlag[] = "death_test_style";
-const char kDeathTestUseFork[] = "death_test_use_fork";
-const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
-
-#if GTEST_HAS_DEATH_TEST
-
-// DeathTest is a class that hides much of the complexity of the
-// GTEST_DEATH_TEST_ macro.  It is abstract; its static Create method
-// returns a concrete class that depends on the prevailing death test
-// style, as defined by the --gtest_death_test_style and/or
-// --gtest_internal_run_death_test flags.
-
-// In describing the results of death tests, these terms are used with
-// the corresponding definitions:
-//
-// exit status:  The integer exit information in the format specified
-//               by wait(2)
-// exit code:    The integer code passed to exit(3), _exit(2), or
-//               returned from main()
-class GTEST_API_ DeathTest {
- public:
-  // Create returns false if there was an error determining the
-  // appropriate action to take for the current death test; for example,
-  // if the gtest_death_test_style flag is set to an invalid value.
-  // The LastMessage method will return a more detailed message in that
-  // case.  Otherwise, the DeathTest pointer pointed to by the "test"
-  // argument is set.  If the death test should be skipped, the pointer
-  // is set to NULL; otherwise, it is set to the address of a new concrete
-  // DeathTest object that controls the execution of the current test.
-  static bool Create(const char* statement, const RE* regex,
-                     const char* file, int line, DeathTest** test);
-  DeathTest();
-  virtual ~DeathTest() { }
-
-  // A helper class that aborts a death test when it's deleted.
-  class ReturnSentinel {
-   public:
-    explicit ReturnSentinel(DeathTest* test) : test_(test) { }
-    ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
-   private:
-    DeathTest* const test_;
-    GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
-  } GTEST_ATTRIBUTE_UNUSED_;
-
-  // An enumeration of possible roles that may be taken when a death
-  // test is encountered.  EXECUTE means that the death test logic should
-  // be executed immediately.  OVERSEE means that the program should prepare
-  // the appropriate environment for a child process to execute the death
-  // test, then wait for it to complete.
-  enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
-
-  // An enumeration of the three reasons that a test might be aborted.
-  enum AbortReason {
-    TEST_ENCOUNTERED_RETURN_STATEMENT,
-    TEST_THREW_EXCEPTION,
-    TEST_DID_NOT_DIE
-  };
-
-  // Assumes one of the above roles.
-  virtual TestRole AssumeRole() = 0;
-
-  // Waits for the death test to finish and returns its status.
-  virtual int Wait() = 0;
-
-  // Returns true if the death test passed; that is, the test process
-  // exited during the test, its exit status matches a user-supplied
-  // predicate, and its stderr output matches a user-supplied regular
-  // expression.
-  // The user-supplied predicate may be a macro expression rather
-  // than a function pointer or functor, or else Wait and Passed could
-  // be combined.
-  virtual bool Passed(bool exit_status_ok) = 0;
-
-  // Signals that the death test did not die as expected.
-  virtual void Abort(AbortReason reason) = 0;
-
-  // Returns a human-readable outcome message regarding the outcome of
-  // the last death test.
-  static const char* LastMessage();
-
-  static void set_last_death_test_message(const std::string& message);
-
- private:
-  // A string containing a description of the outcome of the last death test.
-  static std::string last_death_test_message_;
-
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
-};
-
-// Factory interface for death tests.  May be mocked out for testing.
-class DeathTestFactory {
- public:
-  virtual ~DeathTestFactory() { }
-  virtual bool Create(const char* statement, const RE* regex,
-                      const char* file, int line, DeathTest** test) = 0;
-};
-
-// A concrete DeathTestFactory implementation for normal use.
-class DefaultDeathTestFactory : public DeathTestFactory {
- public:
-  virtual bool Create(const char* statement, const RE* regex,
-                      const char* file, int line, DeathTest** test);
-};
-
-// Returns true if exit_status describes a process that was terminated
-// by a signal, or exited normally with a nonzero exit code.
-GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
-
-// Traps C++ exceptions escaping statement and reports them as test
-// failures. Note that trapping SEH exceptions is not implemented here.
-# if GTEST_HAS_EXCEPTIONS
-#  define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
-  try { \
-    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
-  } catch (const ::std::exception& gtest_exception) { \
-    fprintf(\
-        stderr, \
-        "\n%s: Caught std::exception-derived exception escaping the " \
-        "death test statement. Exception message: %s\n", \
-        ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
-        gtest_exception.what()); \
-    fflush(stderr); \
-    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
-  } catch (...) { \
-    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
-  }
-
-# else
-#  define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
-  GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
-
-# endif
-
-// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
-// ASSERT_EXIT*, and EXPECT_EXIT*.
-# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
-  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
-  if (::testing::internal::AlwaysTrue()) { \
-    const ::testing::internal::RE& gtest_regex = (regex); \
-    ::testing::internal::DeathTest* gtest_dt; \
-    if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \
-        __FILE__, __LINE__, &gtest_dt)) { \
-      goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
-    } \
-    if (gtest_dt != NULL) { \
-      ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
-          gtest_dt_ptr(gtest_dt); \
-      switch (gtest_dt->AssumeRole()) { \
-        case ::testing::internal::DeathTest::OVERSEE_TEST: \
-          if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
-            goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
-          } \
-          break; \
-        case ::testing::internal::DeathTest::EXECUTE_TEST: { \
-          ::testing::internal::DeathTest::ReturnSentinel \
-              gtest_sentinel(gtest_dt); \
-          GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
-          gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
-          break; \
-        } \
-        default: \
-          break; \
-      } \
-    } \
-  } else \
-    GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
-      fail(::testing::internal::DeathTest::LastMessage())
-// The symbol "fail" here expands to something into which a message
-// can be streamed.
-
-// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
-// NDEBUG mode. In this case we need the statements to be executed, the regex is
-// ignored, and the macro must accept a streamed message even though the message
-// is never printed.
-# define GTEST_EXECUTE_STATEMENT_(statement, regex) \
-  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
-  if (::testing::internal::AlwaysTrue()) { \
-     GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
-  } else \
-    ::testing::Message()
-
-// A class representing the parsed contents of the
-// --gtest_internal_run_death_test flag, as it existed when
-// RUN_ALL_TESTS was called.
-class InternalRunDeathTestFlag {
- public:
-  InternalRunDeathTestFlag(const std::string& a_file,
-                           int a_line,
-                           int an_index,
-                           int a_write_fd)
-      : file_(a_file), line_(a_line), index_(an_index),
-        write_fd_(a_write_fd) {}
-
-  ~InternalRunDeathTestFlag() {
-    if (write_fd_ >= 0)
-      posix::Close(write_fd_);
-  }
-
-  const std::string& file() const { return file_; }
-  int line() const { return line_; }
-  int index() const { return index_; }
-  int write_fd() const { return write_fd_; }
-
- private:
-  std::string file_;
-  int line_;
-  int index_;
-  int write_fd_;
-
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
-};
-
-// Returns a newly created InternalRunDeathTestFlag object with fields
-// initialized from the GTEST_FLAG(internal_run_death_test) flag if
-// the flag is specified; otherwise returns NULL.
-InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
-
-#else  // GTEST_HAS_DEATH_TEST
-
-// This macro is used for implementing macros such as
-// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
-// death tests are not supported. Those macros must compile on such systems
-// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
-// systems that support death tests. This allows one to write such a macro
-// on a system that does not support death tests and be sure that it will
-// compile on a death-test supporting system.
-//
-// Parameters:
-//   statement -  A statement that a macro such as EXPECT_DEATH would test
-//                for program termination. This macro has to make sure this
-//                statement is compiled but not executed, to ensure that
-//                EXPECT_DEATH_IF_SUPPORTED compiles with a certain
-//                parameter iff EXPECT_DEATH compiles with it.
-//   regex     -  A regex that a macro such as EXPECT_DEATH would use to test
-//                the output of statement.  This parameter has to be
-//                compiled but not evaluated by this macro, to ensure that
-//                this macro only accepts expressions that a macro such as
-//                EXPECT_DEATH would accept.
-//   terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
-//                and a return statement for ASSERT_DEATH_IF_SUPPORTED.
-//                This ensures that ASSERT_DEATH_IF_SUPPORTED will not
-//                compile inside functions where ASSERT_DEATH doesn't
-//                compile.
-//
-//  The branch that has an always false condition is used to ensure that
-//  statement and regex are compiled (and thus syntactically correct) but
-//  never executed. The unreachable code macro protects the terminator
-//  statement from generating an 'unreachable code' warning in case
-//  statement unconditionally returns or throws. The Message constructor at
-//  the end allows the syntax of streaming additional messages into the
-//  macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
-# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
-    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
-    if (::testing::internal::AlwaysTrue()) { \
-      GTEST_LOG_(WARNING) \
-          << "Death tests are not supported on this platform.\n" \
-          << "Statement '" #statement "' cannot be verified."; \
-    } else if (::testing::internal::AlwaysFalse()) { \
-      ::testing::internal::RE::PartialMatch(".*", (regex)); \
-      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
-      terminator; \
-    } else \
-      ::testing::Message()
-
-#endif  // GTEST_HAS_DEATH_TEST
-
-}  // namespace internal
-}  // namespace testing
-
-#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
-
-namespace testing {
-
-// This flag controls the style of death tests.  Valid values are "threadsafe",
-// meaning that the death test child process will re-execute the test binary
-// from the start, running only a single death test, or "fast",
-// meaning that the child process will execute the test logic immediately
-// after forking.
-GTEST_DECLARE_string_(death_test_style);
-
-#if GTEST_HAS_DEATH_TEST
-
-namespace internal {
-
-// Returns a Boolean value indicating whether the caller is currently
-// executing in the context of the death test child process.  Tools such as
-// Valgrind heap checkers may need this to modify their behavior in death
-// tests.  IMPORTANT: This is an internal utility.  Using it may break the
-// implementation of death tests.  User code MUST NOT use it.
-GTEST_API_ bool InDeathTestChild();
-
-}  // namespace internal
-
-// The following macros are useful for writing death tests.
-
-// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
-// executed:
-//
-//   1. It generates a warning if there is more than one active
-//   thread.  This is because it's safe to fork() or clone() only
-//   when there is a single thread.
-//
-//   2. The parent process clone()s a sub-process and runs the death
-//   test in it; the sub-process exits with code 0 at the end of the
-//   death test, if it hasn't exited already.
-//
-//   3. The parent process waits for the sub-process to terminate.
-//
-//   4. The parent process checks the exit code and error message of
-//   the sub-process.
-//
-// Examples:
-//
-//   ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
-//   for (int i = 0; i < 5; i++) {
-//     EXPECT_DEATH(server.ProcessRequest(i),
-//                  "Invalid request .* in ProcessRequest()")
-//                  << "Failed to die on request " << i;
-//   }
-//
-//   ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
-//
-//   bool KilledBySIGHUP(int exit_code) {
-//     return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
-//   }
-//
-//   ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
-//
-// On the regular expressions used in death tests:
-//
-//   On POSIX-compliant systems (*nix), we use the <regex.h> library,
-//   which uses the POSIX extended regex syntax.
-//
-//   On other platforms (e.g. Windows), we only support a simple regex
-//   syntax implemented as part of Google Test.  This limited
-//   implementation should be enough most of the time when writing
-//   death tests; though it lacks many features you can find in PCRE
-//   or POSIX extended regex syntax.  For example, we don't support
-//   union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
-//   repetition count ("x{5,7}"), among others.
-//
-//   Below is the syntax that we do support.  We chose it to be a
-//   subset of both PCRE and POSIX extended regex, so it's easy to
-//   learn wherever you come from.  In the following: 'A' denotes a
-//   literal character, period (.), or a single \\ escape sequence;
-//   'x' and 'y' denote regular expressions; 'm' and 'n' are for
-//   natural numbers.
-//
-//     c     matches any literal character c
-//     \\d   matches any decimal digit
-//     \\D   matches any character that's not a decimal digit
-//     \\f   matches \f
-//     \\n   matches \n
-//     \\r   matches \r
-//     \\s   matches any ASCII whitespace, including \n
-//     \\S   matches any character that's not a whitespace
-//     \\t   matches \t
-//     \\v   matches \v
-//     \\w   matches any letter, _, or decimal digit
-//     \\W   matches any character that \\w doesn't match
-//     \\c   matches any literal character c, which must be a punctuation
-//     .     matches any single character except \n
-//     A?    matches 0 or 1 occurrences of A
-//     A*    matches 0 or many occurrences of A
-//     A+    matches 1 or many occurrences of A
-//     ^     matches the beginning of a string (not that of each line)
-//     $     matches the end of a string (not that of each line)
-//     xy    matches x followed by y
-//
-//   If you accidentally use PCRE or POSIX extended regex features
-//   not implemented by us, you will get a run-time failure.  In that
-//   case, please try to rewrite your regular expression within the
-//   above syntax.
-//
-//   This implementation is *not* meant to be as highly tuned or robust
-//   as a compiled regex library, but should perform well enough for a
-//   death test, which already incurs significant overhead by launching
-//   a child process.
-//
-// Known caveats:
-//
-//   A "threadsafe" style death test obtains the path to the test
-//   program from argv[0] and re-executes it in the sub-process.  For
-//   simplicity, the current implementation doesn't search the PATH
-//   when launching the sub-process.  This means that the user must
-//   invoke the test program via a path that contains at least one
-//   path separator (e.g. path/to/foo_test and
-//   /absolute/path/to/bar_test are fine, but foo_test is not).  This
-//   is rarely a problem as people usually don't put the test binary
-//   directory in PATH.
-//
-// TODO(wan@google.com): make thread-safe death tests search the PATH.
-
-// Asserts that a given statement causes the program to exit, with an
-// integer exit status that satisfies predicate, and emitting error output
-// that matches regex.
-# define ASSERT_EXIT(statement, predicate, regex) \
-    GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
-
-// Like ASSERT_EXIT, but continues on to successive tests in the
-// test case, if any:
-# define EXPECT_EXIT(statement, predicate, regex) \
-    GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
-
-// Asserts that a given statement causes the program to exit, either by
-// explicitly exiting with a nonzero exit code or being killed by a
-// signal, and emitting error output that matches regex.
-# define ASSERT_DEATH(statement, regex) \
-    ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
-
-// Like ASSERT_DEATH, but continues on to successive tests in the
-// test case, if any:
-# define EXPECT_DEATH(statement, regex) \
-    EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
-
-// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
-
-// Tests that an exit code describes a normal exit with a given exit code.
-class GTEST_API_ ExitedWithCode {
- public:
-  explicit ExitedWithCode(int exit_code);
-  bool operator()(int exit_status) const;
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ExitedWithCode& other);
-
-  const int exit_code_;
-};
-
-# if !GTEST_OS_WINDOWS
-// Tests that an exit code describes an exit due to termination by a
-// given signal.
-class GTEST_API_ KilledBySignal {
- public:
-  explicit KilledBySignal(int signum);
-  bool operator()(int exit_status) const;
- private:
-  const int signum_;
-};
-# endif  // !GTEST_OS_WINDOWS
-
-// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
-// The death testing framework causes this to have interesting semantics,
-// since the sideeffects of the call are only visible in opt mode, and not
-// in debug mode.
-//
-// In practice, this can be used to test functions that utilize the
-// LOG(DFATAL) macro using the following style:
-//
-// int DieInDebugOr12(int* sideeffect) {
-//   if (sideeffect) {
-//     *sideeffect = 12;
-//   }
-//   LOG(DFATAL) << "death";
-//   return 12;
-// }
-//
-// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
-//   int sideeffect = 0;
-//   // Only asserts in dbg.
-//   EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
-//
-// #ifdef NDEBUG
-//   // opt-mode has sideeffect visible.
-//   EXPECT_EQ(12, sideeffect);
-// #else
-//   // dbg-mode no visible sideeffect.
-//   EXPECT_EQ(0, sideeffect);
-// #endif
-// }
-//
-// This will assert that DieInDebugReturn12InOpt() crashes in debug
-// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
-// appropriate fallback value (12 in this case) in opt mode. If you
-// need to test that a function has appropriate side-effects in opt
-// mode, include assertions against the side-effects.  A general
-// pattern for this is:
-//
-// EXPECT_DEBUG_DEATH({
-//   // Side-effects here will have an effect after this statement in
-//   // opt mode, but none in debug mode.
-//   EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
-// }, "death");
-//
-# ifdef NDEBUG
-
-#  define EXPECT_DEBUG_DEATH(statement, regex) \
-  GTEST_EXECUTE_STATEMENT_(statement, regex)
-
-#  define ASSERT_DEBUG_DEATH(statement, regex) \
-  GTEST_EXECUTE_STATEMENT_(statement, regex)
-
-# else
-
-#  define EXPECT_DEBUG_DEATH(statement, regex) \
-  EXPECT_DEATH(statement, regex)
-
-#  define ASSERT_DEBUG_DEATH(statement, regex) \
-  ASSERT_DEATH(statement, regex)
-
-# endif  // NDEBUG for EXPECT_DEBUG_DEATH
-#endif  // GTEST_HAS_DEATH_TEST
-
-// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
-// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
-// death tests are supported; otherwise they just issue a warning.  This is
-// useful when you are combining death test assertions with normal test
-// assertions in one test.
-#if GTEST_HAS_DEATH_TEST
-# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
-    EXPECT_DEATH(statement, regex)
-# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
-    ASSERT_DEATH(statement, regex)
-#else
-# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
-    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
-# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
-    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
-#endif
-
-}  // namespace testing
-
-#endif  // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
-// This file was GENERATED by command:
-//     pump.py gtest-param-test.h.pump
-// DO NOT EDIT BY HAND!!!
-
-// Copyright 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.
-//
-// Authors: vladl@google.com (Vlad Losev)
-//
-// Macros and functions for implementing parameterized tests
-// in Google C++ Testing Framework (Google Test)
-//
-// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
-//
-#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
-#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
-
-
-// Value-parameterized tests allow you to test your code with different
-// parameters without writing multiple copies of the same test.
-//
-// Here is how you use value-parameterized tests:
-
-#if 0
-
-// To write value-parameterized tests, first you should define a fixture
-// class. It is usually derived from testing::TestWithParam<T> (see below for
-// another inheritance scheme that's sometimes useful in more complicated
-// class hierarchies), where the type of your parameter values.
-// TestWithParam<T> is itself derived from testing::Test. T can be any
-// copyable type. If it's a raw pointer, you are responsible for managing the
-// lifespan of the pointed values.
-
-class FooTest : public ::testing::TestWithParam<const char*> {
-  // You can implement all the usual class fixture members here.
-};
-
-// Then, use the TEST_P macro to define as many parameterized tests
-// for this fixture as you want. The _P suffix is for "parameterized"
-// or "pattern", whichever you prefer to think.
-
-TEST_P(FooTest, DoesBlah) {
-  // Inside a test, access the test parameter with the GetParam() method
-  // of the TestWithParam<T> class:
-  EXPECT_TRUE(foo.Blah(GetParam()));
-  ...
-}
-
-TEST_P(FooTest, HasBlahBlah) {
-  ...
-}
-
-// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
-// case with any set of parameters you want. Google Test defines a number
-// of functions for generating test parameters. They return what we call
-// (surprise!) parameter generators. Here is a  summary of them, which
-// are all in the testing namespace:
-//
-//
-//  Range(begin, end [, step]) - Yields values {begin, begin+step,
-//                               begin+step+step, ...}. The values do not
-//                               include end. step defaults to 1.
-//  Values(v1, v2, ..., vN)    - Yields values {v1, v2, ..., vN}.
-//  ValuesIn(container)        - Yields values from a C-style array, an STL
-//  ValuesIn(begin,end)          container, or an iterator range [begin, end).
-//  Bool()                     - Yields sequence {false, true}.
-//  Combine(g1, g2, ..., gN)   - Yields all combinations (the Cartesian product
-//                               for the math savvy) of the values generated
-//                               by the N generators.
-//
-// For more details, see comments at the definitions of these functions below
-// in this file.
-//
-// The following statement will instantiate tests from the FooTest test case
-// each with parameter values "meeny", "miny", and "moe".
-
-INSTANTIATE_TEST_CASE_P(InstantiationName,
-                        FooTest,
-                        Values("meeny", "miny", "moe"));
-
-// To distinguish different instances of the pattern, (yes, you
-// can instantiate it more then once) the first argument to the
-// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
-// actual test case name. Remember to pick unique prefixes for different
-// instantiations. The tests from the instantiation above will have
-// these names:
-//
-//    * InstantiationName/FooTest.DoesBlah/0 for "meeny"
-//    * InstantiationName/FooTest.DoesBlah/1 for "miny"
-//    * InstantiationName/FooTest.DoesBlah/2 for "moe"
-//    * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
-//    * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
-//    * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
-//
-// You can use these names in --gtest_filter.
-//
-// This statement will instantiate all tests from FooTest again, each
-// with parameter values "cat" and "dog":
-
-const char* pets[] = {"cat", "dog"};
-INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
-
-// The tests from the instantiation above will have these names:
-//
-//    * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
-//    * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
-//    * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
-//    * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
-//
-// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
-// in the given test case, whether their definitions come before or
-// AFTER the INSTANTIATE_TEST_CASE_P statement.
-//
-// Please also note that generator expressions (including parameters to the
-// generators) are evaluated in InitGoogleTest(), after main() has started.
-// This allows the user on one hand, to adjust generator parameters in order
-// to dynamically determine a set of tests to run and on the other hand,
-// give the user a chance to inspect the generated tests with Google Test
-// reflection API before RUN_ALL_TESTS() is executed.
-//
-// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
-// for more examples.
-//
-// In the future, we plan to publish the API for defining new parameter
-// generators. But for now this interface remains part of the internal
-// implementation and is subject to change.
-//
-//
-// A parameterized test fixture must be derived from testing::Test and from
-// testing::WithParamInterface<T>, where T is the type of the parameter
-// values. Inheriting from TestWithParam<T> satisfies that requirement because
-// TestWithParam<T> inherits from both Test and WithParamInterface. In more
-// complicated hierarchies, however, it is occasionally useful to inherit
-// separately from Test and WithParamInterface. For example:
-
-class BaseTest : public ::testing::Test {
-  // You can inherit all the usual members for a non-parameterized test
-  // fixture here.
-};
-
-class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
-  // The usual test fixture members go here too.
-};
-
-TEST_F(BaseTest, HasFoo) {
-  // This is an ordinary non-parameterized test.
-}
-
-TEST_P(DerivedTest, DoesBlah) {
-  // GetParam works just the same here as if you inherit from TestWithParam.
-  EXPECT_TRUE(foo.Blah(GetParam()));
-}
-
-#endif  // 0
-
-
-#if !GTEST_OS_SYMBIAN
-# include <utility>
-#endif
-
-// scripts/fuse_gtest.py depends on gtest's own header being #included
-// *unconditionally*.  Therefore these #includes cannot be moved
-// inside #if GTEST_HAS_PARAM_TEST.
-// Copyright 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: vladl@google.com (Vlad Losev)
-
-// Type and function utilities for implementing parameterized tests.
-
-#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
-#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
-
-#include <ctype.h>
-
-#include <iterator>
-#include <set>
-#include <utility>
-#include <vector>
-
-// scripts/fuse_gtest.py depends on gtest's own header being #included
-// *unconditionally*.  Therefore these #includes cannot be moved
-// inside #if GTEST_HAS_PARAM_TEST.
-// Copyright 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.
-//
-// Authors: Dan Egnor (egnor@google.com)
-//
-// A "smart" pointer type with reference tracking.  Every pointer to a
-// particular object is kept on a circular linked list.  When the last pointer
-// to an object is destroyed or reassigned, the object is deleted.
-//
-// Used properly, this deletes the object when the last reference goes away.
-// There are several caveats:
-// - Like all reference counting schemes, cycles lead to leaks.
-// - Each smart pointer is actually two pointers (8 bytes instead of 4).
-// - Every time a pointer is assigned, the entire list of pointers to that
-//   object is traversed.  This class is therefore NOT SUITABLE when there
-//   will often be more than two or three pointers to a particular object.
-// - References are only tracked as long as linked_ptr<> objects are copied.
-//   If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
-//   will happen (double deletion).
-//
-// A good use of this class is storing object references in STL containers.
-// You can safely put linked_ptr<> in a vector<>.
-// Other uses may not be as good.
-//
-// Note: If you use an incomplete type with linked_ptr<>, the class
-// *containing* linked_ptr<> must have a constructor and destructor (even
-// if they do nothing!).
-//
-// Bill Gibbons suggested we use something like this.
-//
-// Thread Safety:
-//   Unlike other linked_ptr implementations, in this implementation
-//   a linked_ptr object is thread-safe in the sense that:
-//     - it's safe to copy linked_ptr objects concurrently,
-//     - it's safe to copy *from* a linked_ptr and read its underlying
-//       raw pointer (e.g. via get()) concurrently, and
-//     - it's safe to write to two linked_ptrs that point to the same
-//       shared object concurrently.
-// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
-// confusion with normal linked_ptr.
-
-#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
-#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
-
-#include <stdlib.h>
-#include <assert.h>
-
-
-namespace testing {
-namespace internal {
-
-// Protects copying of all linked_ptr objects.
-GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
-
-// This is used internally by all instances of linked_ptr<>.  It needs to be
-// a non-template class because different types of linked_ptr<> can refer to
-// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
-// So, it needs to be possible for different types of linked_ptr to participate
-// in the same circular linked list, so we need a single class type here.
-//
-// DO NOT USE THIS CLASS DIRECTLY YOURSELF.  Use linked_ptr<T>.
-class linked_ptr_internal {
- public:
-  // Create a new circle that includes only this instance.
-  void join_new() {
-    next_ = this;
-  }
-
-  // Many linked_ptr operations may change p.link_ for some linked_ptr
-  // variable p in the same circle as this object.  Therefore we need
-  // to prevent two such operations from occurring concurrently.
-  //
-  // Note that different types of linked_ptr objects can coexist in a
-  // circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
-  // linked_ptr<Derived2>).  Therefore we must use a single mutex to
-  // protect all linked_ptr objects.  This can create serious
-  // contention in production code, but is acceptable in a testing
-  // framework.
-
-  // Join an existing circle.
-  void join(linked_ptr_internal const* ptr)
-      GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
-    MutexLock lock(&g_linked_ptr_mutex);
-
-    linked_ptr_internal const* p = ptr;
-    while (p->next_ != ptr) {
-      assert(p->next_ != this &&
-             "Trying to join() a linked ring we are already in. "
-             "Is GMock thread safety enabled?");
-      p = p->next_;
-    }
-    p->next_ = this;
-    next_ = ptr;
-  }
-
-  // Leave whatever circle we're part of.  Returns true if we were the
-  // last member of the circle.  Once this is done, you can join() another.
-  bool depart()
-      GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
-    MutexLock lock(&g_linked_ptr_mutex);
-
-    if (next_ == this) return true;
-    linked_ptr_internal const* p = next_;
-    while (p->next_ != this) {
-      assert(p->next_ != next_ &&
-             "Trying to depart() a linked ring we are not in. "
-             "Is GMock thread safety enabled?");
-      p = p->next_;
-    }
-    p->next_ = next_;
-    return false;
-  }
-
- private:
-  mutable linked_ptr_internal const* next_;
-};
-
-template <typename T>
-class linked_ptr {
- public:
-  typedef T element_type;
-
-  // Take over ownership of a raw pointer.  This should happen as soon as
-  // possible after the object is created.
-  explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
-  ~linked_ptr() { depart(); }
-
-  // Copy an existing linked_ptr<>, adding ourselves to the list of references.
-  template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
-  linked_ptr(linked_ptr const& ptr) {  // NOLINT
-    assert(&ptr != this);
-    copy(&ptr);
-  }
-
-  // Assignment releases the old value and acquires the new.
-  template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
-    depart();
-    copy(&ptr);
-    return *this;
-  }
-
-  linked_ptr& operator=(linked_ptr const& ptr) {
-    if (&ptr != this) {
-      depart();
-      copy(&ptr);
-    }
-    return *this;
-  }
-
-  // Smart pointer members.
-  void reset(T* ptr = NULL) {
-    depart();
-    capture(ptr);
-  }
-  T* get() const { return value_; }
-  T* operator->() const { return value_; }
-  T& operator*() const { return *value_; }
-
-  bool operator==(T* p) const { return value_ == p; }
-  bool operator!=(T* p) const { return value_ != p; }
-  template <typename U>
-  bool operator==(linked_ptr<U> const& ptr) const {
-    return value_ == ptr.get();
-  }
-  template <typename U>
-  bool operator!=(linked_ptr<U> const& ptr) const {
-    return value_ != ptr.get();
-  }
-
- private:
-  template <typename U>
-  friend class linked_ptr;
-
-  T* value_;
-  linked_ptr_internal link_;
-
-  void depart() {
-    if (link_.depart()) delete value_;
-  }
-
-  void capture(T* ptr) {
-    value_ = ptr;
-    link_.join_new();
-  }
-
-  template <typename U> void copy(linked_ptr<U> const* ptr) {
-    value_ = ptr->get();
-    if (value_)
-      link_.join(&ptr->link_);
-    else
-      link_.join_new();
-  }
-};
-
-template<typename T> inline
-bool operator==(T* ptr, const linked_ptr<T>& x) {
-  return ptr == x.get();
-}
-
-template<typename T> inline
-bool operator!=(T* ptr, const linked_ptr<T>& x) {
-  return ptr != x.get();
-}
-
-// A function to convert T* into linked_ptr<T>
-// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
-// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
-template <typename T>
-linked_ptr<T> make_linked_ptr(T* ptr) {
-  return linked_ptr<T>(ptr);
-}
-
-}  // namespace internal
-}  // namespace testing
-
-#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
 // Copyright 2007, Google Inc.
 // All rights reserved.
 //
@@ -10097,10 +8028,54 @@
 // 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: wan@google.com (Zhanyong Wan)
 
-// Google Test - The Google C++ Testing Framework
+// The Google C++ Testing and Mocking Framework (Google Test)
+//
+// This file implements just enough of the matcher interface to allow
+// EXPECT_DEATH and friends to accept a matcher argument.
+
+// IWYU pragma: private, include "testing/base/public/gunit.h"
+// IWYU pragma: friend third_party/googletest/googlemock/.*
+// IWYU pragma: friend third_party/googletest/googletest/.*
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
+#define GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
+
+#include <memory>
+#include <ostream>
+#include <string>
+
+// Copyright 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.
+
+
+// Google Test - The Google C++ Testing and Mocking Framework
 //
 // This file implements a universal value printer that can print a
 // value of any type T:
@@ -10117,6 +8092,10 @@
 //   2. operator<<(ostream&, const T&) defined in either foo or the
 //      global namespace.
 //
+// However if T is an STL-style container then it is printed element-wise
+// unless foo::PrintTo(const T&, ostream*) is defined. Note that
+// operator<<() is ignored for container types.
+//
 // If none of the above is defined, it will print the debug string of
 // the value if it is a protocol buffer, or print the raw bytes in the
 // value otherwise.
@@ -10163,18 +8142,25 @@
 // being defined as many user-defined container types don't have
 // value_type.
 
+// GOOGLETEST_CM0001 DO NOT DELETE
+
 #ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
 #define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
 
+#include <functional>
 #include <ostream>  // NOLINT
 #include <sstream>
 #include <string>
+#include <tuple>
+#include <type_traits>
 #include <utility>
 #include <vector>
 
-#if GTEST_HAS_STD_TUPLE_
-# include <tuple>
-#endif
+#if GTEST_HAS_ABSL
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "absl/types/variant.h"
+#endif  // GTEST_HAS_ABSL
 
 namespace testing {
 
@@ -10194,7 +8180,11 @@
   kProtobuf,              // a protobuf type
   kConvertibleToInteger,  // a type implicitly convertible to BiggestInt
                           // (e.g. a named or unnamed enum type)
-  kOtherType              // anything else
+#if GTEST_HAS_ABSL
+  kConvertibleToStringView,  // a type implicitly convertible to
+                             // absl::string_view
+#endif
+  kOtherType  // anything else
 };
 
 // TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
@@ -10206,7 +8196,8 @@
  public:
   // This default version is called when kTypeKind is kOtherType.
   static void PrintValue(const T& value, ::std::ostream* os) {
-    PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value),
+    PrintBytesInObjectTo(static_cast<const unsigned char*>(
+                             reinterpret_cast<const void*>(&value)),
                          sizeof(value), os);
   }
 };
@@ -10220,10 +8211,10 @@
 class TypeWithoutFormatter<T, kProtobuf> {
  public:
   static void PrintValue(const T& value, ::std::ostream* os) {
-    const ::testing::internal::string short_str = value.ShortDebugString();
-    const ::testing::internal::string pretty_str =
-        short_str.length() <= kProtobufOneLinerMaxLength ?
-        short_str : ("\n" + value.DebugString());
+    std::string pretty_str = value.ShortDebugString();
+    if (pretty_str.length() > kProtobufOneLinerMaxLength) {
+      pretty_str = "\n" + value.DebugString();
+    }
     *os << ("<" + pretty_str + ">");
   }
 };
@@ -10244,6 +8235,19 @@
   }
 };
 
+#if GTEST_HAS_ABSL
+template <typename T>
+class TypeWithoutFormatter<T, kConvertibleToStringView> {
+ public:
+  // Since T has neither operator<< nor PrintTo() but can be implicitly
+  // converted to absl::string_view, we print it as a absl::string_view.
+  //
+  // Note: the implementation is further below, as it depends on
+  // internal::PrintTo symbol which is defined later in the file.
+  static void PrintValue(const T& value, ::std::ostream* os);
+};
+#endif
+
 // Prints the given value to the given ostream.  If the value is a
 // protocol message, its debug string is printed; if it's an enum or
 // of a type implicitly convertible to BiggestInt, it's printed as an
@@ -10271,10 +8275,19 @@
 template <typename Char, typename CharTraits, typename T>
 ::std::basic_ostream<Char, CharTraits>& operator<<(
     ::std::basic_ostream<Char, CharTraits>& os, const T& x) {
-  TypeWithoutFormatter<T,
-      (internal::IsAProtocolMessage<T>::value ? kProtobuf :
-       internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ?
-       kConvertibleToInteger : kOtherType)>::PrintValue(x, &os);
+  TypeWithoutFormatter<T, (internal::IsAProtocolMessage<T>::value
+                               ? kProtobuf
+                               : std::is_convertible<
+                                     const T&, internal::BiggestInt>::value
+                                     ? kConvertibleToInteger
+                                     :
+#if GTEST_HAS_ABSL
+                                     std::is_convertible<
+                                         const T&, absl::string_view>::value
+                                         ? kConvertibleToStringView
+                                         :
+#endif
+                                         kOtherType)>::PrintValue(x, &os);
   return os;
 }
 
@@ -10433,11 +8446,18 @@
 template <typename T>
 void UniversalPrint(const T& value, ::std::ostream* os);
 
+enum DefaultPrinterType {
+  kPrintContainer,
+  kPrintPointer,
+  kPrintFunctionPointer,
+  kPrintOther,
+};
+template <DefaultPrinterType type> struct WrapPrinterType {};
+
 // Used to print an STL-style container when the user doesn't define
 // a PrintTo() for it.
 template <typename C>
-void DefaultPrintTo(IsContainer /* dummy */,
-                    false_type /* is not a pointer */,
+void DefaultPrintTo(WrapPrinterType<kPrintContainer> /* dummy */,
                     const C& container, ::std::ostream* os) {
   const size_t kMaxCount = 32;  // The maximum number of elements to print.
   *os << '{';
@@ -10470,40 +8490,34 @@
 // implementation-defined.  Therefore they will be printed as raw
 // bytes.)
 template <typename T>
-void DefaultPrintTo(IsNotContainer /* dummy */,
-                    true_type /* is a pointer */,
+void DefaultPrintTo(WrapPrinterType<kPrintPointer> /* dummy */,
                     T* p, ::std::ostream* os) {
-  if (p == NULL) {
+  if (p == nullptr) {
     *os << "NULL";
   } else {
-    // C++ doesn't allow casting from a function pointer to any object
-    // pointer.
-    //
-    // IsTrue() silences warnings: "Condition is always true",
-    // "unreachable code".
-    if (IsTrue(ImplicitlyConvertible<T*, const void*>::value)) {
-      // T is not a function type.  We just call << to print p,
-      // relying on ADL to pick up user-defined << for their pointer
-      // types, if any.
-      *os << p;
-    } else {
-      // T is a function type, so '*os << p' doesn't do what we want
-      // (it just prints p as bool).  We want to print p as a const
-      // void*.  However, we cannot cast it to const void* directly,
-      // even using reinterpret_cast, as earlier versions of gcc
-      // (e.g. 3.4.5) cannot compile the cast when p is a function
-      // pointer.  Casting to UInt64 first solves the problem.
-      *os << reinterpret_cast<const void*>(
-          reinterpret_cast<internal::UInt64>(p));
-    }
+    // T is not a function type.  We just call << to print p,
+    // relying on ADL to pick up user-defined << for their pointer
+    // types, if any.
+    *os << p;
+  }
+}
+template <typename T>
+void DefaultPrintTo(WrapPrinterType<kPrintFunctionPointer> /* dummy */,
+                    T* p, ::std::ostream* os) {
+  if (p == nullptr) {
+    *os << "NULL";
+  } else {
+    // T is a function type, so '*os << p' doesn't do what we want
+    // (it just prints p as bool).  We want to print p as a const
+    // void*.
+    *os << reinterpret_cast<const void*>(p);
   }
 }
 
 // Used to print a non-container, non-pointer value when the user
 // doesn't define PrintTo() for it.
 template <typename T>
-void DefaultPrintTo(IsNotContainer /* dummy */,
-                    false_type /* is not a pointer */,
+void DefaultPrintTo(WrapPrinterType<kPrintOther> /* dummy */,
                     const T& value, ::std::ostream* os) {
   ::testing_internal::DefaultPrintNonContainerTo(value, os);
 }
@@ -10521,11 +8535,8 @@
 // wants).
 template <typename T>
 void PrintTo(const T& value, ::std::ostream* os) {
-  // DefaultPrintTo() is overloaded.  The type of its first two
-  // arguments determine which version will be picked.  If T is an
-  // STL-style container, the version for container will be called; if
-  // T is a pointer, the pointer version will be called; otherwise the
-  // generic version will be called.
+  // DefaultPrintTo() is overloaded.  The type of its first argument
+  // determines which version will be picked.
   //
   // Note that we check for container types here, prior to we check
   // for protocol message types in our operator<<.  The rationale is:
@@ -10537,13 +8548,23 @@
   // elements; therefore we check for container types here to ensure
   // that our format is used.
   //
-  // The second argument of DefaultPrintTo() is needed to bypass a bug
-  // in Symbian's C++ compiler that prevents it from picking the right
-  // overload between:
-  //
-  //   PrintTo(const T& x, ...);
-  //   PrintTo(T* x, ...);
-  DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), value, os);
+  // Note that MSVC and clang-cl do allow an implicit conversion from
+  // pointer-to-function to pointer-to-object, but clang-cl warns on it.
+  // So don't use ImplicitlyConvertible if it can be helped since it will
+  // cause this warning, and use a separate overload of DefaultPrintTo for
+  // function pointers so that the `*os << p` in the object pointer overload
+  // doesn't cause that warning either.
+  DefaultPrintTo(
+      WrapPrinterType <
+                  (sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
+              !IsRecursiveContainer<T>::value
+          ? kPrintContainer
+          : !std::is_pointer<T>::value
+                ? kPrintOther
+                : std::is_function<typename std::remove_pointer<T>::type>::value
+                      ? kPrintFunctionPointer
+                      : kPrintPointer > (),
+      value, os);
 }
 
 // The following list of PrintTo() overloads tells
@@ -10650,95 +8671,45 @@
 }
 #endif  // GTEST_HAS_STD_WSTRING
 
-#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
+#if GTEST_HAS_ABSL
+// Overload for absl::string_view.
+inline void PrintTo(absl::string_view sp, ::std::ostream* os) {
+  PrintTo(::std::string(sp), os);
+}
+#endif  // GTEST_HAS_ABSL
+
+inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
+
+template <typename T>
+void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
+  UniversalPrinter<T&>::Print(ref.get(), os);
+}
+
 // Helper function for printing a tuple.  T must be instantiated with
 // a tuple type.
 template <typename T>
-void PrintTupleTo(const T& t, ::std::ostream* os);
-#endif  // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
+void PrintTupleTo(const T&, std::integral_constant<size_t, 0>,
+                  ::std::ostream*) {}
 
-#if GTEST_HAS_TR1_TUPLE
-// Overload for ::std::tr1::tuple.  Needed for printing function arguments,
-// which are packed as tuples.
-
-// Overloaded PrintTo() for tuples of various arities.  We support
-// tuples of up-to 10 fields.  The following implementation works
-// regardless of whether tr1::tuple is implemented using the
-// non-standard variadic template feature or not.
-
-inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) {
-  PrintTupleTo(t, os);
+template <typename T, size_t I>
+void PrintTupleTo(const T& t, std::integral_constant<size_t, I>,
+                  ::std::ostream* os) {
+  PrintTupleTo(t, std::integral_constant<size_t, I - 1>(), os);
+  GTEST_INTENTIONAL_CONST_COND_PUSH_()
+  if (I > 1) {
+    GTEST_INTENTIONAL_CONST_COND_POP_()
+    *os << ", ";
+  }
+  UniversalPrinter<typename std::tuple_element<I - 1, T>::type>::Print(
+      std::get<I - 1>(t), os);
 }
 
-template <typename T1>
-void PrintTo(const ::std::tr1::tuple<T1>& t, ::std::ostream* os) {
-  PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2>
-void PrintTo(const ::std::tr1::tuple<T1, T2>& t, ::std::ostream* os) {
-  PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3>& t, ::std::ostream* os) {
-  PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4>& t, ::std::ostream* os) {
-  PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5>& t,
-             ::std::ostream* os) {
-  PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-          typename T6>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6>& t,
-             ::std::ostream* os) {
-  PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-          typename T6, typename T7>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7>& t,
-             ::std::ostream* os) {
-  PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-          typename T6, typename T7, typename T8>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8>& t,
-             ::std::ostream* os) {
-  PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-          typename T6, typename T7, typename T8, typename T9>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t,
-             ::std::ostream* os) {
-  PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-          typename T6, typename T7, typename T8, typename T9, typename T10>
-void PrintTo(
-    const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t,
-    ::std::ostream* os) {
-  PrintTupleTo(t, os);
-}
-#endif  // GTEST_HAS_TR1_TUPLE
-
-#if GTEST_HAS_STD_TUPLE_
 template <typename... Types>
 void PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {
-  PrintTupleTo(t, os);
+  *os << "(";
+  PrintTupleTo(t, std::integral_constant<size_t, sizeof...(Types)>(), os);
+  *os << ")";
 }
-#endif  // GTEST_HAS_STD_TUPLE_
 
 // Overload for std::pair.
 template <typename T1, typename T2>
@@ -10779,6 +8750,48 @@
   GTEST_DISABLE_MSC_WARNINGS_POP_()
 };
 
+#if GTEST_HAS_ABSL
+
+// Printer for absl::optional
+
+template <typename T>
+class UniversalPrinter<::absl::optional<T>> {
+ public:
+  static void Print(const ::absl::optional<T>& value, ::std::ostream* os) {
+    *os << '(';
+    if (!value) {
+      *os << "nullopt";
+    } else {
+      UniversalPrint(*value, os);
+    }
+    *os << ')';
+  }
+};
+
+// Printer for absl::variant
+
+template <typename... T>
+class UniversalPrinter<::absl::variant<T...>> {
+ public:
+  static void Print(const ::absl::variant<T...>& value, ::std::ostream* os) {
+    *os << '(';
+    absl::visit(Visitor{os}, value);
+    *os << ')';
+  }
+
+ private:
+  struct Visitor {
+    template <typename U>
+    void operator()(const U& u) const {
+      *os << "'" << GetTypeName<U>() << "' with value ";
+      UniversalPrint(u, os);
+    }
+    ::std::ostream* os;
+  };
+};
+
+#endif  // GTEST_HAS_ABSL
+
 // UniversalPrintArray(begin, len, os) prints an array of 'len'
 // elements, starting at address 'begin'.
 template <typename T>
@@ -10792,7 +8805,6 @@
     // If the array has more than kThreshold elements, we'll have to
     // omit some details by printing only the first and the last
     // kChunkSize elements.
-    // TODO(wan@google.com): let the user control the threshold using a flag.
     if (len <= kThreshold) {
       PrintRawArrayTo(begin, len, os);
     } else {
@@ -10871,10 +8883,10 @@
 class UniversalTersePrinter<const char*> {
  public:
   static void Print(const char* str, ::std::ostream* os) {
-    if (str == NULL) {
+    if (str == nullptr) {
       *os << "NULL";
     } else {
-      UniversalPrint(string(str), os);
+      UniversalPrint(std::string(str), os);
     }
   }
 };
@@ -10891,7 +8903,7 @@
 class UniversalTersePrinter<const wchar_t*> {
  public:
   static void Print(const wchar_t* str, ::std::ostream* os) {
-    if (str == NULL) {
+    if (str == nullptr) {
       *os << "NULL";
     } else {
       UniversalPrint(::std::wstring(str), os);
@@ -10925,110 +8937,22 @@
   UniversalPrinter<T1>::Print(value, os);
 }
 
-typedef ::std::vector<string> Strings;
-
-// TuplePolicy<TupleT> must provide:
-// - tuple_size
-//     size of tuple TupleT.
-// - get<size_t I>(const TupleT& t)
-//     static function extracting element I of tuple TupleT.
-// - tuple_element<size_t I>::type
-//     type of element I of tuple TupleT.
-template <typename TupleT>
-struct TuplePolicy;
-
-#if GTEST_HAS_TR1_TUPLE
-template <typename TupleT>
-struct TuplePolicy {
-  typedef TupleT Tuple;
-  static const size_t tuple_size = ::std::tr1::tuple_size<Tuple>::value;
-
-  template <size_t I>
-  struct tuple_element : ::std::tr1::tuple_element<I, Tuple> {};
-
-  template <size_t I>
-  static typename AddReference<
-      const typename ::std::tr1::tuple_element<I, Tuple>::type>::type get(
-      const Tuple& tuple) {
-    return ::std::tr1::get<I>(tuple);
-  }
-};
-template <typename TupleT>
-const size_t TuplePolicy<TupleT>::tuple_size;
-#endif  // GTEST_HAS_TR1_TUPLE
-
-#if GTEST_HAS_STD_TUPLE_
-template <typename... Types>
-struct TuplePolicy< ::std::tuple<Types...> > {
-  typedef ::std::tuple<Types...> Tuple;
-  static const size_t tuple_size = ::std::tuple_size<Tuple>::value;
-
-  template <size_t I>
-  struct tuple_element : ::std::tuple_element<I, Tuple> {};
-
-  template <size_t I>
-  static const typename ::std::tuple_element<I, Tuple>::type& get(
-      const Tuple& tuple) {
-    return ::std::get<I>(tuple);
-  }
-};
-template <typename... Types>
-const size_t TuplePolicy< ::std::tuple<Types...> >::tuple_size;
-#endif  // GTEST_HAS_STD_TUPLE_
-
-#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
-// This helper template allows PrintTo() for tuples and
-// UniversalTersePrintTupleFieldsToStrings() to be defined by
-// induction on the number of tuple fields.  The idea is that
-// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
-// fields in tuple t, and can be defined in terms of
-// TuplePrefixPrinter<N - 1>.
-//
-// The inductive case.
-template <size_t N>
-struct TuplePrefixPrinter {
-  // Prints the first N fields of a tuple.
-  template <typename Tuple>
-  static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
-    TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
-    GTEST_INTENTIONAL_CONST_COND_PUSH_()
-    if (N > 1) {
-    GTEST_INTENTIONAL_CONST_COND_POP_()
-      *os << ", ";
-    }
-    UniversalPrinter<
-        typename TuplePolicy<Tuple>::template tuple_element<N - 1>::type>
-        ::Print(TuplePolicy<Tuple>::template get<N - 1>(t), os);
-  }
+typedef ::std::vector< ::std::string> Strings;
 
   // Tersely prints the first N fields of a tuple to a string vector,
   // one element for each field.
-  template <typename Tuple>
-  static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
-    TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings);
-    ::std::stringstream ss;
-    UniversalTersePrint(TuplePolicy<Tuple>::template get<N - 1>(t), &ss);
-    strings->push_back(ss.str());
-  }
-};
-
-// Base case.
-template <>
-struct TuplePrefixPrinter<0> {
-  template <typename Tuple>
-  static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}
-
-  template <typename Tuple>
-  static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
-};
-
-// Helper function for printing a tuple.
-// Tuple must be either std::tr1::tuple or std::tuple type.
 template <typename Tuple>
-void PrintTupleTo(const Tuple& t, ::std::ostream* os) {
-  *os << "(";
-  TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>::PrintPrefixTo(t, os);
-  *os << ")";
+void TersePrintPrefixToStrings(const Tuple&, std::integral_constant<size_t, 0>,
+                               Strings*) {}
+template <typename Tuple, size_t I>
+void TersePrintPrefixToStrings(const Tuple& t,
+                               std::integral_constant<size_t, I>,
+                               Strings* strings) {
+  TersePrintPrefixToStrings(t, std::integral_constant<size_t, I - 1>(),
+                            strings);
+  ::std::stringstream ss;
+  UniversalTersePrint(std::get<I - 1>(t), &ss);
+  strings->push_back(ss.str());
 }
 
 // Prints the fields of a tuple tersely to a string vector, one
@@ -11037,14 +8961,24 @@
 template <typename Tuple>
 Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
   Strings result;
-  TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>::
-      TersePrintPrefixToStrings(value, &result);
+  TersePrintPrefixToStrings(
+      value, std::integral_constant<size_t, std::tuple_size<Tuple>::value>(),
+      &result);
   return result;
 }
-#endif  // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
 
 }  // namespace internal
 
+#if GTEST_HAS_ABSL
+namespace internal2 {
+template <typename T>
+void TypeWithoutFormatter<T, kConvertibleToStringView>::PrintValue(
+    const T& value, ::std::ostream* os) {
+  internal::PrintTo(absl::string_view(value), os);
+}
+}  // namespace internal2
+#endif
+
 template <typename T>
 ::std::string PrintToString(const T& value) {
   ::std::stringstream ss;
@@ -11090,8 +9024,8 @@
 // installation of gTest.
 // It will be included from gtest-printers.h and the overrides in this file
 // will be visible to everyone.
-// See documentation at gtest/gtest-printers.h for details on how to define a
-// custom printer.
+//
+// Injection point for custom user configurations. See README for details
 //
 // ** Custom implementation starts here **
 
@@ -11102,10 +9036,1570 @@
 
 #endif  // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
 
-#if GTEST_HAS_PARAM_TEST
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(
+    4251 5046 /* class A needs to have dll-interface to be used by clients of
+                 class B */
+    /* Symbol involving type with internal linkage not defined */)
 
 namespace testing {
 
+// To implement a matcher Foo for type T, define:
+//   1. a class FooMatcherImpl that implements the
+//      MatcherInterface<T> interface, and
+//   2. a factory function that creates a Matcher<T> object from a
+//      FooMatcherImpl*.
+//
+// The two-level delegation design makes it possible to allow a user
+// to write "v" instead of "Eq(v)" where a Matcher is expected, which
+// is impossible if we pass matchers by pointers.  It also eases
+// ownership management as Matcher objects can now be copied like
+// plain values.
+
+// MatchResultListener is an abstract class.  Its << operator can be
+// used by a matcher to explain why a value matches or doesn't match.
+//
+class MatchResultListener {
+ public:
+  // Creates a listener object with the given underlying ostream.  The
+  // listener does not own the ostream, and does not dereference it
+  // in the constructor or destructor.
+  explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
+  virtual ~MatchResultListener() = 0;  // Makes this class abstract.
+
+  // Streams x to the underlying ostream; does nothing if the ostream
+  // is NULL.
+  template <typename T>
+  MatchResultListener& operator<<(const T& x) {
+    if (stream_ != nullptr) *stream_ << x;
+    return *this;
+  }
+
+  // Returns the underlying ostream.
+  ::std::ostream* stream() { return stream_; }
+
+  // Returns true iff the listener is interested in an explanation of
+  // the match result.  A matcher's MatchAndExplain() method can use
+  // this information to avoid generating the explanation when no one
+  // intends to hear it.
+  bool IsInterested() const { return stream_ != nullptr; }
+
+ private:
+  ::std::ostream* const stream_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener);
+};
+
+inline MatchResultListener::~MatchResultListener() {
+}
+
+// An instance of a subclass of this knows how to describe itself as a
+// matcher.
+class MatcherDescriberInterface {
+ public:
+  virtual ~MatcherDescriberInterface() {}
+
+  // Describes this matcher to an ostream.  The function should print
+  // a verb phrase that describes the property a value matching this
+  // matcher should have.  The subject of the verb phrase is the value
+  // being matched.  For example, the DescribeTo() method of the Gt(7)
+  // matcher prints "is greater than 7".
+  virtual void DescribeTo(::std::ostream* os) const = 0;
+
+  // Describes the negation of this matcher to an ostream.  For
+  // example, if the description of this matcher is "is greater than
+  // 7", the negated description could be "is not greater than 7".
+  // You are not required to override this when implementing
+  // MatcherInterface, but it is highly advised so that your matcher
+  // can produce good error messages.
+  virtual void DescribeNegationTo(::std::ostream* os) const {
+    *os << "not (";
+    DescribeTo(os);
+    *os << ")";
+  }
+};
+
+// The implementation of a matcher.
+template <typename T>
+class MatcherInterface : public MatcherDescriberInterface {
+ public:
+  // Returns true iff the matcher matches x; also explains the match
+  // result to 'listener' if necessary (see the next paragraph), in
+  // the form of a non-restrictive relative clause ("which ...",
+  // "whose ...", etc) that describes x.  For example, the
+  // MatchAndExplain() method of the Pointee(...) matcher should
+  // generate an explanation like "which points to ...".
+  //
+  // Implementations of MatchAndExplain() should add an explanation of
+  // the match result *if and only if* they can provide additional
+  // information that's not already present (or not obvious) in the
+  // print-out of x and the matcher's description.  Whether the match
+  // succeeds is not a factor in deciding whether an explanation is
+  // needed, as sometimes the caller needs to print a failure message
+  // when the match succeeds (e.g. when the matcher is used inside
+  // Not()).
+  //
+  // For example, a "has at least 10 elements" matcher should explain
+  // what the actual element count is, regardless of the match result,
+  // as it is useful information to the reader; on the other hand, an
+  // "is empty" matcher probably only needs to explain what the actual
+  // size is when the match fails, as it's redundant to say that the
+  // size is 0 when the value is already known to be empty.
+  //
+  // You should override this method when defining a new matcher.
+  //
+  // It's the responsibility of the caller (Google Test) to guarantee
+  // that 'listener' is not NULL.  This helps to simplify a matcher's
+  // implementation when it doesn't care about the performance, as it
+  // can talk to 'listener' without checking its validity first.
+  // However, in order to implement dummy listeners efficiently,
+  // listener->stream() may be NULL.
+  virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;
+
+  // Inherits these methods from MatcherDescriberInterface:
+  //   virtual void DescribeTo(::std::ostream* os) const = 0;
+  //   virtual void DescribeNegationTo(::std::ostream* os) const;
+};
+
+namespace internal {
+
+// Converts a MatcherInterface<T> to a MatcherInterface<const T&>.
+template <typename T>
+class MatcherInterfaceAdapter : public MatcherInterface<const T&> {
+ public:
+  explicit MatcherInterfaceAdapter(const MatcherInterface<T>* impl)
+      : impl_(impl) {}
+  ~MatcherInterfaceAdapter() override { delete impl_; }
+
+  void DescribeTo(::std::ostream* os) const override { impl_->DescribeTo(os); }
+
+  void DescribeNegationTo(::std::ostream* os) const override {
+    impl_->DescribeNegationTo(os);
+  }
+
+  bool MatchAndExplain(const T& x,
+                       MatchResultListener* listener) const override {
+    return impl_->MatchAndExplain(x, listener);
+  }
+
+ private:
+  const MatcherInterface<T>* const impl_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(MatcherInterfaceAdapter);
+};
+
+struct AnyEq {
+  template <typename A, typename B>
+  bool operator()(const A& a, const B& b) const { return a == b; }
+};
+struct AnyNe {
+  template <typename A, typename B>
+  bool operator()(const A& a, const B& b) const { return a != b; }
+};
+struct AnyLt {
+  template <typename A, typename B>
+  bool operator()(const A& a, const B& b) const { return a < b; }
+};
+struct AnyGt {
+  template <typename A, typename B>
+  bool operator()(const A& a, const B& b) const { return a > b; }
+};
+struct AnyLe {
+  template <typename A, typename B>
+  bool operator()(const A& a, const B& b) const { return a <= b; }
+};
+struct AnyGe {
+  template <typename A, typename B>
+  bool operator()(const A& a, const B& b) const { return a >= b; }
+};
+
+// A match result listener that ignores the explanation.
+class DummyMatchResultListener : public MatchResultListener {
+ public:
+  DummyMatchResultListener() : MatchResultListener(nullptr) {}
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener);
+};
+
+// A match result listener that forwards the explanation to a given
+// ostream.  The difference between this and MatchResultListener is
+// that the former is concrete.
+class StreamMatchResultListener : public MatchResultListener {
+ public:
+  explicit StreamMatchResultListener(::std::ostream* os)
+      : MatchResultListener(os) {}
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener);
+};
+
+// An internal class for implementing Matcher<T>, which will derive
+// from it.  We put functionalities common to all Matcher<T>
+// specializations here to avoid code duplication.
+template <typename T>
+class MatcherBase {
+ public:
+  // Returns true iff the matcher matches x; also explains the match
+  // result to 'listener'.
+  bool MatchAndExplain(const T& x, MatchResultListener* listener) const {
+    return impl_->MatchAndExplain(x, listener);
+  }
+
+  // Returns true iff this matcher matches x.
+  bool Matches(const T& x) const {
+    DummyMatchResultListener dummy;
+    return MatchAndExplain(x, &dummy);
+  }
+
+  // Describes this matcher to an ostream.
+  void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
+
+  // Describes the negation of this matcher to an ostream.
+  void DescribeNegationTo(::std::ostream* os) const {
+    impl_->DescribeNegationTo(os);
+  }
+
+  // Explains why x matches, or doesn't match, the matcher.
+  void ExplainMatchResultTo(const T& x, ::std::ostream* os) const {
+    StreamMatchResultListener listener(os);
+    MatchAndExplain(x, &listener);
+  }
+
+  // Returns the describer for this matcher object; retains ownership
+  // of the describer, which is only guaranteed to be alive when
+  // this matcher object is alive.
+  const MatcherDescriberInterface* GetDescriber() const {
+    return impl_.get();
+  }
+
+ protected:
+  MatcherBase() {}
+
+  // Constructs a matcher from its implementation.
+  explicit MatcherBase(const MatcherInterface<const T&>* impl) : impl_(impl) {}
+
+  template <typename U>
+  explicit MatcherBase(
+      const MatcherInterface<U>* impl,
+      typename internal::EnableIf<
+          !internal::IsSame<U, const U&>::value>::type* = nullptr)
+      : impl_(new internal::MatcherInterfaceAdapter<U>(impl)) {}
+
+  MatcherBase(const MatcherBase&) = default;
+  MatcherBase& operator=(const MatcherBase&) = default;
+  MatcherBase(MatcherBase&&) = default;
+  MatcherBase& operator=(MatcherBase&&) = default;
+
+  virtual ~MatcherBase() {}
+
+ private:
+  std::shared_ptr<const MatcherInterface<const T&>> impl_;
+};
+
+}  // namespace internal
+
+// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)
+// object that can check whether a value of type T matches.  The
+// implementation of Matcher<T> is just a std::shared_ptr to const
+// MatcherInterface<T>.  Don't inherit from Matcher!
+template <typename T>
+class Matcher : public internal::MatcherBase<T> {
+ public:
+  // Constructs a null matcher.  Needed for storing Matcher objects in STL
+  // containers.  A default-constructed matcher is not yet initialized.  You
+  // cannot use it until a valid value has been assigned to it.
+  explicit Matcher() {}  // NOLINT
+
+  // Constructs a matcher from its implementation.
+  explicit Matcher(const MatcherInterface<const T&>* impl)
+      : internal::MatcherBase<T>(impl) {}
+
+  template <typename U>
+  explicit Matcher(const MatcherInterface<U>* impl,
+                   typename internal::EnableIf<
+                       !internal::IsSame<U, const U&>::value>::type* = nullptr)
+      : internal::MatcherBase<T>(impl) {}
+
+  // Implicit constructor here allows people to write
+  // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
+  Matcher(T value);  // NOLINT
+};
+
+// The following two specializations allow the user to write str
+// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
+// matcher is expected.
+template <>
+class GTEST_API_ Matcher<const std::string&>
+    : public internal::MatcherBase<const std::string&> {
+ public:
+  Matcher() {}
+
+  explicit Matcher(const MatcherInterface<const std::string&>* impl)
+      : internal::MatcherBase<const std::string&>(impl) {}
+
+  // Allows the user to write str instead of Eq(str) sometimes, where
+  // str is a std::string object.
+  Matcher(const std::string& s);  // NOLINT
+
+#if GTEST_HAS_GLOBAL_STRING
+  // Allows the user to write str instead of Eq(str) sometimes, where
+  // str is a ::string object.
+  Matcher(const ::string& s);  // NOLINT
+#endif                         // GTEST_HAS_GLOBAL_STRING
+
+  // Allows the user to write "foo" instead of Eq("foo") sometimes.
+  Matcher(const char* s);  // NOLINT
+};
+
+template <>
+class GTEST_API_ Matcher<std::string>
+    : public internal::MatcherBase<std::string> {
+ public:
+  Matcher() {}
+
+  explicit Matcher(const MatcherInterface<const std::string&>* impl)
+      : internal::MatcherBase<std::string>(impl) {}
+  explicit Matcher(const MatcherInterface<std::string>* impl)
+      : internal::MatcherBase<std::string>(impl) {}
+
+  // Allows the user to write str instead of Eq(str) sometimes, where
+  // str is a string object.
+  Matcher(const std::string& s);  // NOLINT
+
+#if GTEST_HAS_GLOBAL_STRING
+  // Allows the user to write str instead of Eq(str) sometimes, where
+  // str is a ::string object.
+  Matcher(const ::string& s);  // NOLINT
+#endif                         // GTEST_HAS_GLOBAL_STRING
+
+  // Allows the user to write "foo" instead of Eq("foo") sometimes.
+  Matcher(const char* s);  // NOLINT
+};
+
+#if GTEST_HAS_GLOBAL_STRING
+// The following two specializations allow the user to write str
+// instead of Eq(str) and "foo" instead of Eq("foo") when a ::string
+// matcher is expected.
+template <>
+class GTEST_API_ Matcher<const ::string&>
+    : public internal::MatcherBase<const ::string&> {
+ public:
+  Matcher() {}
+
+  explicit Matcher(const MatcherInterface<const ::string&>* impl)
+      : internal::MatcherBase<const ::string&>(impl) {}
+
+  // Allows the user to write str instead of Eq(str) sometimes, where
+  // str is a std::string object.
+  Matcher(const std::string& s);  // NOLINT
+
+  // Allows the user to write str instead of Eq(str) sometimes, where
+  // str is a ::string object.
+  Matcher(const ::string& s);  // NOLINT
+
+  // Allows the user to write "foo" instead of Eq("foo") sometimes.
+  Matcher(const char* s);  // NOLINT
+};
+
+template <>
+class GTEST_API_ Matcher< ::string>
+    : public internal::MatcherBase< ::string> {
+ public:
+  Matcher() {}
+
+  explicit Matcher(const MatcherInterface<const ::string&>* impl)
+      : internal::MatcherBase< ::string>(impl) {}
+  explicit Matcher(const MatcherInterface< ::string>* impl)
+      : internal::MatcherBase< ::string>(impl) {}
+
+  // Allows the user to write str instead of Eq(str) sometimes, where
+  // str is a std::string object.
+  Matcher(const std::string& s);  // NOLINT
+
+  // Allows the user to write str instead of Eq(str) sometimes, where
+  // str is a ::string object.
+  Matcher(const ::string& s);  // NOLINT
+
+  // Allows the user to write "foo" instead of Eq("foo") sometimes.
+  Matcher(const char* s);  // NOLINT
+};
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_ABSL
+// The following two specializations allow the user to write str
+// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
+// matcher is expected.
+template <>
+class GTEST_API_ Matcher<const absl::string_view&>
+    : public internal::MatcherBase<const absl::string_view&> {
+ public:
+  Matcher() {}
+
+  explicit Matcher(const MatcherInterface<const absl::string_view&>* impl)
+      : internal::MatcherBase<const absl::string_view&>(impl) {}
+
+  // Allows the user to write str instead of Eq(str) sometimes, where
+  // str is a std::string object.
+  Matcher(const std::string& s);  // NOLINT
+
+#if GTEST_HAS_GLOBAL_STRING
+  // Allows the user to write str instead of Eq(str) sometimes, where
+  // str is a ::string object.
+  Matcher(const ::string& s);  // NOLINT
+#endif                         // GTEST_HAS_GLOBAL_STRING
+
+  // Allows the user to write "foo" instead of Eq("foo") sometimes.
+  Matcher(const char* s);  // NOLINT
+
+  // Allows the user to pass absl::string_views directly.
+  Matcher(absl::string_view s);  // NOLINT
+};
+
+template <>
+class GTEST_API_ Matcher<absl::string_view>
+    : public internal::MatcherBase<absl::string_view> {
+ public:
+  Matcher() {}
+
+  explicit Matcher(const MatcherInterface<const absl::string_view&>* impl)
+      : internal::MatcherBase<absl::string_view>(impl) {}
+  explicit Matcher(const MatcherInterface<absl::string_view>* impl)
+      : internal::MatcherBase<absl::string_view>(impl) {}
+
+  // Allows the user to write str instead of Eq(str) sometimes, where
+  // str is a std::string object.
+  Matcher(const std::string& s);  // NOLINT
+
+#if GTEST_HAS_GLOBAL_STRING
+  // Allows the user to write str instead of Eq(str) sometimes, where
+  // str is a ::string object.
+  Matcher(const ::string& s);  // NOLINT
+#endif                         // GTEST_HAS_GLOBAL_STRING
+
+  // Allows the user to write "foo" instead of Eq("foo") sometimes.
+  Matcher(const char* s);  // NOLINT
+
+  // Allows the user to pass absl::string_views directly.
+  Matcher(absl::string_view s);  // NOLINT
+};
+#endif  // GTEST_HAS_ABSL
+
+// Prints a matcher in a human-readable format.
+template <typename T>
+std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
+  matcher.DescribeTo(&os);
+  return os;
+}
+
+// The PolymorphicMatcher class template makes it easy to implement a
+// polymorphic matcher (i.e. a matcher that can match values of more
+// than one type, e.g. Eq(n) and NotNull()).
+//
+// To define a polymorphic matcher, a user should provide an Impl
+// class that has a DescribeTo() method and a DescribeNegationTo()
+// method, and define a member function (or member function template)
+//
+//   bool MatchAndExplain(const Value& value,
+//                        MatchResultListener* listener) const;
+//
+// See the definition of NotNull() for a complete example.
+template <class Impl>
+class PolymorphicMatcher {
+ public:
+  explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
+
+  // Returns a mutable reference to the underlying matcher
+  // implementation object.
+  Impl& mutable_impl() { return impl_; }
+
+  // Returns an immutable reference to the underlying matcher
+  // implementation object.
+  const Impl& impl() const { return impl_; }
+
+  template <typename T>
+  operator Matcher<T>() const {
+    return Matcher<T>(new MonomorphicImpl<const T&>(impl_));
+  }
+
+ private:
+  template <typename T>
+  class MonomorphicImpl : public MatcherInterface<T> {
+   public:
+    explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
+
+    virtual void DescribeTo(::std::ostream* os) const { impl_.DescribeTo(os); }
+
+    virtual void DescribeNegationTo(::std::ostream* os) const {
+      impl_.DescribeNegationTo(os);
+    }
+
+    virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
+      return impl_.MatchAndExplain(x, listener);
+    }
+
+   private:
+    const Impl impl_;
+  };
+
+  Impl impl_;
+};
+
+// Creates a matcher from its implementation.
+// DEPRECATED: Especially in the generic code, prefer:
+//   Matcher<T>(new MyMatcherImpl<const T&>(...));
+//
+// MakeMatcher may create a Matcher that accepts its argument by value, which
+// leads to unnecessary copies & lack of support for non-copyable types.
+template <typename T>
+inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
+  return Matcher<T>(impl);
+}
+
+// Creates a polymorphic matcher from its implementation.  This is
+// easier to use than the PolymorphicMatcher<Impl> constructor as it
+// doesn't require you to explicitly write the template argument, e.g.
+//
+//   MakePolymorphicMatcher(foo);
+// vs
+//   PolymorphicMatcher<TypeOfFoo>(foo);
+template <class Impl>
+inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
+  return PolymorphicMatcher<Impl>(impl);
+}
+
+namespace internal {
+// Implements a matcher that compares a given value with a
+// pre-supplied value using one of the ==, <=, <, etc, operators.  The
+// two values being compared don't have to have the same type.
+//
+// The matcher defined here is polymorphic (for example, Eq(5) can be
+// used to match an int, a short, a double, etc).  Therefore we use
+// a template type conversion operator in the implementation.
+//
+// The following template definition assumes that the Rhs parameter is
+// a "bare" type (i.e. neither 'const T' nor 'T&').
+template <typename D, typename Rhs, typename Op>
+class ComparisonBase {
+ public:
+  explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
+  template <typename Lhs>
+  operator Matcher<Lhs>() const {
+    return Matcher<Lhs>(new Impl<const Lhs&>(rhs_));
+  }
+
+ private:
+  template <typename T>
+  static const T& Unwrap(const T& v) { return v; }
+  template <typename T>
+  static const T& Unwrap(std::reference_wrapper<T> v) { return v; }
+
+  template <typename Lhs, typename = Rhs>
+  class Impl : public MatcherInterface<Lhs> {
+   public:
+    explicit Impl(const Rhs& rhs) : rhs_(rhs) {}
+    bool MatchAndExplain(Lhs lhs,
+                         MatchResultListener* /* listener */) const override {
+      return Op()(lhs, Unwrap(rhs_));
+    }
+    void DescribeTo(::std::ostream* os) const override {
+      *os << D::Desc() << " ";
+      UniversalPrint(Unwrap(rhs_), os);
+    }
+    void DescribeNegationTo(::std::ostream* os) const override {
+      *os << D::NegatedDesc() <<  " ";
+      UniversalPrint(Unwrap(rhs_), os);
+    }
+
+   private:
+    Rhs rhs_;
+  };
+  Rhs rhs_;
+};
+
+template <typename Rhs>
+class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
+ public:
+  explicit EqMatcher(const Rhs& rhs)
+      : ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { }
+  static const char* Desc() { return "is equal to"; }
+  static const char* NegatedDesc() { return "isn't equal to"; }
+};
+template <typename Rhs>
+class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
+ public:
+  explicit NeMatcher(const Rhs& rhs)
+      : ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { }
+  static const char* Desc() { return "isn't equal to"; }
+  static const char* NegatedDesc() { return "is equal to"; }
+};
+template <typename Rhs>
+class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
+ public:
+  explicit LtMatcher(const Rhs& rhs)
+      : ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { }
+  static const char* Desc() { return "is <"; }
+  static const char* NegatedDesc() { return "isn't <"; }
+};
+template <typename Rhs>
+class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
+ public:
+  explicit GtMatcher(const Rhs& rhs)
+      : ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { }
+  static const char* Desc() { return "is >"; }
+  static const char* NegatedDesc() { return "isn't >"; }
+};
+template <typename Rhs>
+class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
+ public:
+  explicit LeMatcher(const Rhs& rhs)
+      : ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { }
+  static const char* Desc() { return "is <="; }
+  static const char* NegatedDesc() { return "isn't <="; }
+};
+template <typename Rhs>
+class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
+ public:
+  explicit GeMatcher(const Rhs& rhs)
+      : ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { }
+  static const char* Desc() { return "is >="; }
+  static const char* NegatedDesc() { return "isn't >="; }
+};
+
+// Implements polymorphic matchers MatchesRegex(regex) and
+// ContainsRegex(regex), which can be used as a Matcher<T> as long as
+// T can be converted to a string.
+class MatchesRegexMatcher {
+ public:
+  MatchesRegexMatcher(const RE* regex, bool full_match)
+      : regex_(regex), full_match_(full_match) {}
+
+#if GTEST_HAS_ABSL
+  bool MatchAndExplain(const absl::string_view& s,
+                       MatchResultListener* listener) const {
+    return MatchAndExplain(string(s), listener);
+  }
+#endif  // GTEST_HAS_ABSL
+
+  // Accepts pointer types, particularly:
+  //   const char*
+  //   char*
+  //   const wchar_t*
+  //   wchar_t*
+  template <typename CharType>
+  bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
+    return s != nullptr && MatchAndExplain(std::string(s), listener);
+  }
+
+  // Matches anything that can convert to std::string.
+  //
+  // This is a template, not just a plain function with const std::string&,
+  // because absl::string_view has some interfering non-explicit constructors.
+  template <class MatcheeStringType>
+  bool MatchAndExplain(const MatcheeStringType& s,
+                       MatchResultListener* /* listener */) const {
+    const std::string& s2(s);
+    return full_match_ ? RE::FullMatch(s2, *regex_)
+                       : RE::PartialMatch(s2, *regex_);
+  }
+
+  void DescribeTo(::std::ostream* os) const {
+    *os << (full_match_ ? "matches" : "contains") << " regular expression ";
+    UniversalPrinter<std::string>::Print(regex_->pattern(), os);
+  }
+
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "doesn't " << (full_match_ ? "match" : "contain")
+        << " regular expression ";
+    UniversalPrinter<std::string>::Print(regex_->pattern(), os);
+  }
+
+ private:
+  const std::shared_ptr<const RE> regex_;
+  const bool full_match_;
+};
+}  // namespace internal
+
+// Matches a string that fully matches regular expression 'regex'.
+// The matcher takes ownership of 'regex'.
+inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
+    const internal::RE* regex) {
+  return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
+}
+inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
+    const std::string& regex) {
+  return MatchesRegex(new internal::RE(regex));
+}
+
+// Matches a string that contains regular expression 'regex'.
+// The matcher takes ownership of 'regex'.
+inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
+    const internal::RE* regex) {
+  return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
+}
+inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
+    const std::string& regex) {
+  return ContainsRegex(new internal::RE(regex));
+}
+
+// Creates a polymorphic matcher that matches anything equal to x.
+// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
+// wouldn't compile.
+template <typename T>
+inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }
+
+// Constructs a Matcher<T> from a 'value' of type T.  The constructed
+// matcher matches any value that's equal to 'value'.
+template <typename T>
+Matcher<T>::Matcher(T value) { *this = Eq(value); }
+
+// Creates a monomorphic matcher that matches anything with type Lhs
+// and equal to rhs.  A user may need to use this instead of Eq(...)
+// in order to resolve an overloading ambiguity.
+//
+// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))
+// or Matcher<T>(x), but more readable than the latter.
+//
+// We could define similar monomorphic matchers for other comparison
+// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do
+// it yet as those are used much less than Eq() in practice.  A user
+// can always write Matcher<T>(Lt(5)) to be explicit about the type,
+// for example.
+template <typename Lhs, typename Rhs>
+inline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); }
+
+// Creates a polymorphic matcher that matches anything >= x.
+template <typename Rhs>
+inline internal::GeMatcher<Rhs> Ge(Rhs x) {
+  return internal::GeMatcher<Rhs>(x);
+}
+
+// Creates a polymorphic matcher that matches anything > x.
+template <typename Rhs>
+inline internal::GtMatcher<Rhs> Gt(Rhs x) {
+  return internal::GtMatcher<Rhs>(x);
+}
+
+// Creates a polymorphic matcher that matches anything <= x.
+template <typename Rhs>
+inline internal::LeMatcher<Rhs> Le(Rhs x) {
+  return internal::LeMatcher<Rhs>(x);
+}
+
+// Creates a polymorphic matcher that matches anything < x.
+template <typename Rhs>
+inline internal::LtMatcher<Rhs> Lt(Rhs x) {
+  return internal::LtMatcher<Rhs>(x);
+}
+
+// Creates a polymorphic matcher that matches anything != x.
+template <typename Rhs>
+inline internal::NeMatcher<Rhs> Ne(Rhs x) {
+  return internal::NeMatcher<Rhs>(x);
+}
+}  // namespace testing
+
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251 5046
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
+
+#include <stdio.h>
+#include <memory>
+
+namespace testing {
+namespace internal {
+
+GTEST_DECLARE_string_(internal_run_death_test);
+
+// Names of the flags (needed for parsing Google Test flags).
+const char kDeathTestStyleFlag[] = "death_test_style";
+const char kDeathTestUseFork[] = "death_test_use_fork";
+const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
+
+#if GTEST_HAS_DEATH_TEST
+
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
+// DeathTest is a class that hides much of the complexity of the
+// GTEST_DEATH_TEST_ macro.  It is abstract; its static Create method
+// returns a concrete class that depends on the prevailing death test
+// style, as defined by the --gtest_death_test_style and/or
+// --gtest_internal_run_death_test flags.
+
+// In describing the results of death tests, these terms are used with
+// the corresponding definitions:
+//
+// exit status:  The integer exit information in the format specified
+//               by wait(2)
+// exit code:    The integer code passed to exit(3), _exit(2), or
+//               returned from main()
+class GTEST_API_ DeathTest {
+ public:
+  // Create returns false if there was an error determining the
+  // appropriate action to take for the current death test; for example,
+  // if the gtest_death_test_style flag is set to an invalid value.
+  // The LastMessage method will return a more detailed message in that
+  // case.  Otherwise, the DeathTest pointer pointed to by the "test"
+  // argument is set.  If the death test should be skipped, the pointer
+  // is set to NULL; otherwise, it is set to the address of a new concrete
+  // DeathTest object that controls the execution of the current test.
+  static bool Create(const char* statement, Matcher<const std::string&> matcher,
+                     const char* file, int line, DeathTest** test);
+  DeathTest();
+  virtual ~DeathTest() { }
+
+  // A helper class that aborts a death test when it's deleted.
+  class ReturnSentinel {
+   public:
+    explicit ReturnSentinel(DeathTest* test) : test_(test) { }
+    ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
+   private:
+    DeathTest* const test_;
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
+  } GTEST_ATTRIBUTE_UNUSED_;
+
+  // An enumeration of possible roles that may be taken when a death
+  // test is encountered.  EXECUTE means that the death test logic should
+  // be executed immediately.  OVERSEE means that the program should prepare
+  // the appropriate environment for a child process to execute the death
+  // test, then wait for it to complete.
+  enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
+
+  // An enumeration of the three reasons that a test might be aborted.
+  enum AbortReason {
+    TEST_ENCOUNTERED_RETURN_STATEMENT,
+    TEST_THREW_EXCEPTION,
+    TEST_DID_NOT_DIE
+  };
+
+  // Assumes one of the above roles.
+  virtual TestRole AssumeRole() = 0;
+
+  // Waits for the death test to finish and returns its status.
+  virtual int Wait() = 0;
+
+  // Returns true if the death test passed; that is, the test process
+  // exited during the test, its exit status matches a user-supplied
+  // predicate, and its stderr output matches a user-supplied regular
+  // expression.
+  // The user-supplied predicate may be a macro expression rather
+  // than a function pointer or functor, or else Wait and Passed could
+  // be combined.
+  virtual bool Passed(bool exit_status_ok) = 0;
+
+  // Signals that the death test did not die as expected.
+  virtual void Abort(AbortReason reason) = 0;
+
+  // Returns a human-readable outcome message regarding the outcome of
+  // the last death test.
+  static const char* LastMessage();
+
+  static void set_last_death_test_message(const std::string& message);
+
+ private:
+  // A string containing a description of the outcome of the last death test.
+  static std::string last_death_test_message_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
+};
+
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251
+
+// Factory interface for death tests.  May be mocked out for testing.
+class DeathTestFactory {
+ public:
+  virtual ~DeathTestFactory() { }
+  virtual bool Create(const char* statement,
+                      Matcher<const std::string&> matcher, const char* file,
+                      int line, DeathTest** test) = 0;
+};
+
+// A concrete DeathTestFactory implementation for normal use.
+class DefaultDeathTestFactory : public DeathTestFactory {
+ public:
+  bool Create(const char* statement, Matcher<const std::string&> matcher,
+              const char* file, int line, DeathTest** test) override;
+};
+
+// Returns true if exit_status describes a process that was terminated
+// by a signal, or exited normally with a nonzero exit code.
+GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
+
+// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
+// and interpreted as a regex (rather than an Eq matcher) for legacy
+// compatibility.
+inline Matcher<const ::std::string&> MakeDeathTestMatcher(
+    ::testing::internal::RE regex) {
+  return ContainsRegex(regex.pattern());
+}
+inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
+  return ContainsRegex(regex);
+}
+inline Matcher<const ::std::string&> MakeDeathTestMatcher(
+    const ::std::string& regex) {
+  return ContainsRegex(regex);
+}
+#if GTEST_HAS_GLOBAL_STRING
+inline Matcher<const ::std::string&> MakeDeathTestMatcher(
+    const ::string& regex) {
+  return ContainsRegex(regex);
+}
+#endif
+
+// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
+// used directly.
+inline Matcher<const ::std::string&> MakeDeathTestMatcher(
+    Matcher<const ::std::string&> matcher) {
+  return matcher;
+}
+
+// Traps C++ exceptions escaping statement and reports them as test
+// failures. Note that trapping SEH exceptions is not implemented here.
+# if GTEST_HAS_EXCEPTIONS
+#  define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
+  try { \
+    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+  } catch (const ::std::exception& gtest_exception) { \
+    fprintf(\
+        stderr, \
+        "\n%s: Caught std::exception-derived exception escaping the " \
+        "death test statement. Exception message: %s\n", \
+        ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
+        gtest_exception.what()); \
+    fflush(stderr); \
+    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
+  } catch (...) { \
+    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
+  }
+
+# else
+#  define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
+  GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
+
+# endif
+
+// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
+// ASSERT_EXIT*, and EXPECT_EXIT*.
+#define GTEST_DEATH_TEST_(statement, predicate, regex_or_matcher, fail)        \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                                \
+  if (::testing::internal::AlwaysTrue()) {                                     \
+    ::testing::internal::DeathTest* gtest_dt;                                  \
+    if (!::testing::internal::DeathTest::Create(                               \
+            #statement,                                                        \
+            ::testing::internal::MakeDeathTestMatcher(regex_or_matcher),       \
+            __FILE__, __LINE__, &gtest_dt)) {                                  \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__);                        \
+    }                                                                          \
+    if (gtest_dt != nullptr) {                                                 \
+      std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \
+      switch (gtest_dt->AssumeRole()) {                                        \
+        case ::testing::internal::DeathTest::OVERSEE_TEST:                     \
+          if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) {                \
+            goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__);                  \
+          }                                                                    \
+          break;                                                               \
+        case ::testing::internal::DeathTest::EXECUTE_TEST: {                   \
+          ::testing::internal::DeathTest::ReturnSentinel gtest_sentinel(       \
+              gtest_dt);                                                       \
+          GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt);            \
+          gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE);   \
+          break;                                                               \
+        }                                                                      \
+        default:                                                               \
+          break;                                                               \
+      }                                                                        \
+    }                                                                          \
+  } else                                                                       \
+    GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__)                                \
+        : fail(::testing::internal::DeathTest::LastMessage())
+// The symbol "fail" here expands to something into which a message
+// can be streamed.
+
+// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
+// NDEBUG mode. In this case we need the statements to be executed and the macro
+// must accept a streamed message even though the message is never printed.
+// The regex object is not evaluated, but it is used to prevent "unused"
+// warnings and to avoid an expression that doesn't compile in debug mode.
+#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher)    \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_                                  \
+  if (::testing::internal::AlwaysTrue()) {                       \
+    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);   \
+  } else if (!::testing::internal::AlwaysTrue()) {               \
+    ::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
+  } else                                                         \
+    ::testing::Message()
+
+// A class representing the parsed contents of the
+// --gtest_internal_run_death_test flag, as it existed when
+// RUN_ALL_TESTS was called.
+class InternalRunDeathTestFlag {
+ public:
+  InternalRunDeathTestFlag(const std::string& a_file,
+                           int a_line,
+                           int an_index,
+                           int a_write_fd)
+      : file_(a_file), line_(a_line), index_(an_index),
+        write_fd_(a_write_fd) {}
+
+  ~InternalRunDeathTestFlag() {
+    if (write_fd_ >= 0)
+      posix::Close(write_fd_);
+  }
+
+  const std::string& file() const { return file_; }
+  int line() const { return line_; }
+  int index() const { return index_; }
+  int write_fd() const { return write_fd_; }
+
+ private:
+  std::string file_;
+  int line_;
+  int index_;
+  int write_fd_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
+};
+
+// Returns a newly created InternalRunDeathTestFlag object with fields
+// initialized from the GTEST_FLAG(internal_run_death_test) flag if
+// the flag is specified; otherwise returns NULL.
+InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
+
+namespace testing {
+
+// This flag controls the style of death tests.  Valid values are "threadsafe",
+// meaning that the death test child process will re-execute the test binary
+// from the start, running only a single death test, or "fast",
+// meaning that the child process will execute the test logic immediately
+// after forking.
+GTEST_DECLARE_string_(death_test_style);
+
+#if GTEST_HAS_DEATH_TEST
+
+namespace internal {
+
+// Returns a Boolean value indicating whether the caller is currently
+// executing in the context of the death test child process.  Tools such as
+// Valgrind heap checkers may need this to modify their behavior in death
+// tests.  IMPORTANT: This is an internal utility.  Using it may break the
+// implementation of death tests.  User code MUST NOT use it.
+GTEST_API_ bool InDeathTestChild();
+
+}  // namespace internal
+
+// The following macros are useful for writing death tests.
+
+// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
+// executed:
+//
+//   1. It generates a warning if there is more than one active
+//   thread.  This is because it's safe to fork() or clone() only
+//   when there is a single thread.
+//
+//   2. The parent process clone()s a sub-process and runs the death
+//   test in it; the sub-process exits with code 0 at the end of the
+//   death test, if it hasn't exited already.
+//
+//   3. The parent process waits for the sub-process to terminate.
+//
+//   4. The parent process checks the exit code and error message of
+//   the sub-process.
+//
+// Examples:
+//
+//   ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
+//   for (int i = 0; i < 5; i++) {
+//     EXPECT_DEATH(server.ProcessRequest(i),
+//                  "Invalid request .* in ProcessRequest()")
+//                  << "Failed to die on request " << i;
+//   }
+//
+//   ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
+//
+//   bool KilledBySIGHUP(int exit_code) {
+//     return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
+//   }
+//
+//   ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
+//
+// On the regular expressions used in death tests:
+//
+//   GOOGLETEST_CM0005 DO NOT DELETE
+//   On POSIX-compliant systems (*nix), we use the <regex.h> library,
+//   which uses the POSIX extended regex syntax.
+//
+//   On other platforms (e.g. Windows or Mac), we only support a simple regex
+//   syntax implemented as part of Google Test.  This limited
+//   implementation should be enough most of the time when writing
+//   death tests; though it lacks many features you can find in PCRE
+//   or POSIX extended regex syntax.  For example, we don't support
+//   union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
+//   repetition count ("x{5,7}"), among others.
+//
+//   Below is the syntax that we do support.  We chose it to be a
+//   subset of both PCRE and POSIX extended regex, so it's easy to
+//   learn wherever you come from.  In the following: 'A' denotes a
+//   literal character, period (.), or a single \\ escape sequence;
+//   'x' and 'y' denote regular expressions; 'm' and 'n' are for
+//   natural numbers.
+//
+//     c     matches any literal character c
+//     \\d   matches any decimal digit
+//     \\D   matches any character that's not a decimal digit
+//     \\f   matches \f
+//     \\n   matches \n
+//     \\r   matches \r
+//     \\s   matches any ASCII whitespace, including \n
+//     \\S   matches any character that's not a whitespace
+//     \\t   matches \t
+//     \\v   matches \v
+//     \\w   matches any letter, _, or decimal digit
+//     \\W   matches any character that \\w doesn't match
+//     \\c   matches any literal character c, which must be a punctuation
+//     .     matches any single character except \n
+//     A?    matches 0 or 1 occurrences of A
+//     A*    matches 0 or many occurrences of A
+//     A+    matches 1 or many occurrences of A
+//     ^     matches the beginning of a string (not that of each line)
+//     $     matches the end of a string (not that of each line)
+//     xy    matches x followed by y
+//
+//   If you accidentally use PCRE or POSIX extended regex features
+//   not implemented by us, you will get a run-time failure.  In that
+//   case, please try to rewrite your regular expression within the
+//   above syntax.
+//
+//   This implementation is *not* meant to be as highly tuned or robust
+//   as a compiled regex library, but should perform well enough for a
+//   death test, which already incurs significant overhead by launching
+//   a child process.
+//
+// Known caveats:
+//
+//   A "threadsafe" style death test obtains the path to the test
+//   program from argv[0] and re-executes it in the sub-process.  For
+//   simplicity, the current implementation doesn't search the PATH
+//   when launching the sub-process.  This means that the user must
+//   invoke the test program via a path that contains at least one
+//   path separator (e.g. path/to/foo_test and
+//   /absolute/path/to/bar_test are fine, but foo_test is not).  This
+//   is rarely a problem as people usually don't put the test binary
+//   directory in PATH.
+//
+
+// Asserts that a given statement causes the program to exit, with an
+// integer exit status that satisfies predicate, and emitting error output
+// that matches regex.
+# define ASSERT_EXIT(statement, predicate, regex) \
+    GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
+
+// Like ASSERT_EXIT, but continues on to successive tests in the
+// test suite, if any:
+# define EXPECT_EXIT(statement, predicate, regex) \
+    GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
+
+// Asserts that a given statement causes the program to exit, either by
+// explicitly exiting with a nonzero exit code or being killed by a
+// signal, and emitting error output that matches regex.
+# define ASSERT_DEATH(statement, regex) \
+    ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
+
+// Like ASSERT_DEATH, but continues on to successive tests in the
+// test suite, if any:
+# define EXPECT_DEATH(statement, regex) \
+    EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
+
+// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
+
+// Tests that an exit code describes a normal exit with a given exit code.
+class GTEST_API_ ExitedWithCode {
+ public:
+  explicit ExitedWithCode(int exit_code);
+  bool operator()(int exit_status) const;
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ExitedWithCode& other);
+
+  const int exit_code_;
+};
+
+# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
+// Tests that an exit code describes an exit due to termination by a
+// given signal.
+// GOOGLETEST_CM0006 DO NOT DELETE
+class GTEST_API_ KilledBySignal {
+ public:
+  explicit KilledBySignal(int signum);
+  bool operator()(int exit_status) const;
+ private:
+  const int signum_;
+};
+# endif  // !GTEST_OS_WINDOWS
+
+// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
+// The death testing framework causes this to have interesting semantics,
+// since the sideeffects of the call are only visible in opt mode, and not
+// in debug mode.
+//
+// In practice, this can be used to test functions that utilize the
+// LOG(DFATAL) macro using the following style:
+//
+// int DieInDebugOr12(int* sideeffect) {
+//   if (sideeffect) {
+//     *sideeffect = 12;
+//   }
+//   LOG(DFATAL) << "death";
+//   return 12;
+// }
+//
+// TEST(TestSuite, TestDieOr12WorksInDgbAndOpt) {
+//   int sideeffect = 0;
+//   // Only asserts in dbg.
+//   EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
+//
+// #ifdef NDEBUG
+//   // opt-mode has sideeffect visible.
+//   EXPECT_EQ(12, sideeffect);
+// #else
+//   // dbg-mode no visible sideeffect.
+//   EXPECT_EQ(0, sideeffect);
+// #endif
+// }
+//
+// This will assert that DieInDebugReturn12InOpt() crashes in debug
+// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
+// appropriate fallback value (12 in this case) in opt mode. If you
+// need to test that a function has appropriate side-effects in opt
+// mode, include assertions against the side-effects.  A general
+// pattern for this is:
+//
+// EXPECT_DEBUG_DEATH({
+//   // Side-effects here will have an effect after this statement in
+//   // opt mode, but none in debug mode.
+//   EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
+// }, "death");
+//
+# ifdef NDEBUG
+
+#  define EXPECT_DEBUG_DEATH(statement, regex) \
+  GTEST_EXECUTE_STATEMENT_(statement, regex)
+
+#  define ASSERT_DEBUG_DEATH(statement, regex) \
+  GTEST_EXECUTE_STATEMENT_(statement, regex)
+
+# else
+
+#  define EXPECT_DEBUG_DEATH(statement, regex) \
+  EXPECT_DEATH(statement, regex)
+
+#  define ASSERT_DEBUG_DEATH(statement, regex) \
+  ASSERT_DEATH(statement, regex)
+
+# endif  // NDEBUG for EXPECT_DEBUG_DEATH
+#endif  // GTEST_HAS_DEATH_TEST
+
+// This macro is used for implementing macros such as
+// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
+// death tests are not supported. Those macros must compile on such systems
+// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
+// systems that support death tests. This allows one to write such a macro
+// on a system that does not support death tests and be sure that it will
+// compile on a death-test supporting system. It is exposed publicly so that
+// systems that have death-tests with stricter requirements than
+// GTEST_HAS_DEATH_TEST can write their own equivalent of
+// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED.
+//
+// Parameters:
+//   statement -  A statement that a macro such as EXPECT_DEATH would test
+//                for program termination. This macro has to make sure this
+//                statement is compiled but not executed, to ensure that
+//                EXPECT_DEATH_IF_SUPPORTED compiles with a certain
+//                parameter iff EXPECT_DEATH compiles with it.
+//   regex     -  A regex that a macro such as EXPECT_DEATH would use to test
+//                the output of statement.  This parameter has to be
+//                compiled but not evaluated by this macro, to ensure that
+//                this macro only accepts expressions that a macro such as
+//                EXPECT_DEATH would accept.
+//   terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
+//                and a return statement for ASSERT_DEATH_IF_SUPPORTED.
+//                This ensures that ASSERT_DEATH_IF_SUPPORTED will not
+//                compile inside functions where ASSERT_DEATH doesn't
+//                compile.
+//
+//  The branch that has an always false condition is used to ensure that
+//  statement and regex are compiled (and thus syntactically correct) but
+//  never executed. The unreachable code macro protects the terminator
+//  statement from generating an 'unreachable code' warning in case
+//  statement unconditionally returns or throws. The Message constructor at
+//  the end allows the syntax of streaming additional messages into the
+//  macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
+# define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \
+    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+    if (::testing::internal::AlwaysTrue()) { \
+      GTEST_LOG_(WARNING) \
+          << "Death tests are not supported on this platform.\n" \
+          << "Statement '" #statement "' cannot be verified."; \
+    } else if (::testing::internal::AlwaysFalse()) { \
+      ::testing::internal::RE::PartialMatch(".*", (regex)); \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+      terminator; \
+    } else \
+      ::testing::Message()
+
+// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
+// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
+// death tests are supported; otherwise they just issue a warning.  This is
+// useful when you are combining death test assertions with normal test
+// assertions in one test.
+#if GTEST_HAS_DEATH_TEST
+# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
+    EXPECT_DEATH(statement, regex)
+# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
+    ASSERT_DEATH(statement, regex)
+#else
+# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
+    GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, )
+# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
+    GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return)
+#endif
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
+// Copyright 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.
+//
+// Macros and functions for implementing parameterized tests
+// in Google C++ Testing and Mocking Framework (Google Test)
+//
+// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+// GOOGLETEST_CM0001 DO NOT DELETE
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+
+
+// Value-parameterized tests allow you to test your code with different
+// parameters without writing multiple copies of the same test.
+//
+// Here is how you use value-parameterized tests:
+
+#if 0
+
+// To write value-parameterized tests, first you should define a fixture
+// class. It is usually derived from testing::TestWithParam<T> (see below for
+// another inheritance scheme that's sometimes useful in more complicated
+// class hierarchies), where the type of your parameter values.
+// TestWithParam<T> is itself derived from testing::Test. T can be any
+// copyable type. If it's a raw pointer, you are responsible for managing the
+// lifespan of the pointed values.
+
+class FooTest : public ::testing::TestWithParam<const char*> {
+  // You can implement all the usual class fixture members here.
+};
+
+// Then, use the TEST_P macro to define as many parameterized tests
+// for this fixture as you want. The _P suffix is for "parameterized"
+// or "pattern", whichever you prefer to think.
+
+TEST_P(FooTest, DoesBlah) {
+  // Inside a test, access the test parameter with the GetParam() method
+  // of the TestWithParam<T> class:
+  EXPECT_TRUE(foo.Blah(GetParam()));
+  ...
+}
+
+TEST_P(FooTest, HasBlahBlah) {
+  ...
+}
+
+// Finally, you can use INSTANTIATE_TEST_SUITE_P to instantiate the test
+// case with any set of parameters you want. Google Test defines a number
+// of functions for generating test parameters. They return what we call
+// (surprise!) parameter generators. Here is a summary of them, which
+// are all in the testing namespace:
+//
+//
+//  Range(begin, end [, step]) - Yields values {begin, begin+step,
+//                               begin+step+step, ...}. The values do not
+//                               include end. step defaults to 1.
+//  Values(v1, v2, ..., vN)    - Yields values {v1, v2, ..., vN}.
+//  ValuesIn(container)        - Yields values from a C-style array, an STL
+//  ValuesIn(begin,end)          container, or an iterator range [begin, end).
+//  Bool()                     - Yields sequence {false, true}.
+//  Combine(g1, g2, ..., gN)   - Yields all combinations (the Cartesian product
+//                               for the math savvy) of the values generated
+//                               by the N generators.
+//
+// For more details, see comments at the definitions of these functions below
+// in this file.
+//
+// The following statement will instantiate tests from the FooTest test suite
+// each with parameter values "meeny", "miny", and "moe".
+
+INSTANTIATE_TEST_SUITE_P(InstantiationName,
+                         FooTest,
+                         Values("meeny", "miny", "moe"));
+
+// To distinguish different instances of the pattern, (yes, you
+// can instantiate it more then once) the first argument to the
+// INSTANTIATE_TEST_SUITE_P macro is a prefix that will be added to the
+// actual test suite name. Remember to pick unique prefixes for different
+// instantiations. The tests from the instantiation above will have
+// these names:
+//
+//    * InstantiationName/FooTest.DoesBlah/0 for "meeny"
+//    * InstantiationName/FooTest.DoesBlah/1 for "miny"
+//    * InstantiationName/FooTest.DoesBlah/2 for "moe"
+//    * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
+//    * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
+//    * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
+//
+// You can use these names in --gtest_filter.
+//
+// This statement will instantiate all tests from FooTest again, each
+// with parameter values "cat" and "dog":
+
+const char* pets[] = {"cat", "dog"};
+INSTANTIATE_TEST_SUITE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
+
+// The tests from the instantiation above will have these names:
+//
+//    * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
+//    * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
+//    * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
+//    * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
+//
+// Please note that INSTANTIATE_TEST_SUITE_P will instantiate all tests
+// in the given test suite, whether their definitions come before or
+// AFTER the INSTANTIATE_TEST_SUITE_P statement.
+//
+// Please also note that generator expressions (including parameters to the
+// generators) are evaluated in InitGoogleTest(), after main() has started.
+// This allows the user on one hand, to adjust generator parameters in order
+// to dynamically determine a set of tests to run and on the other hand,
+// give the user a chance to inspect the generated tests with Google Test
+// reflection API before RUN_ALL_TESTS() is executed.
+//
+// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
+// for more examples.
+//
+// In the future, we plan to publish the API for defining new parameter
+// generators. But for now this interface remains part of the internal
+// implementation and is subject to change.
+//
+//
+// A parameterized test fixture must be derived from testing::Test and from
+// testing::WithParamInterface<T>, where T is the type of the parameter
+// values. Inheriting from TestWithParam<T> satisfies that requirement because
+// TestWithParam<T> inherits from both Test and WithParamInterface. In more
+// complicated hierarchies, however, it is occasionally useful to inherit
+// separately from Test and WithParamInterface. For example:
+
+class BaseTest : public ::testing::Test {
+  // You can inherit all the usual members for a non-parameterized test
+  // fixture here.
+};
+
+class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
+  // The usual test fixture members go here too.
+};
+
+TEST_F(BaseTest, HasFoo) {
+  // This is an ordinary non-parameterized test.
+}
+
+TEST_P(DerivedTest, DoesBlah) {
+  // GetParam works just the same here as if you inherit from TestWithParam.
+  EXPECT_TRUE(foo.Blah(GetParam()));
+}
+
+#endif  // 0
+
+#include <utility>
+
+// Copyright 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.
+
+
+// Type and function utilities for implementing parameterized tests.
+
+// GOOGLETEST_CM0001 DO NOT DELETE
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+
+#include <ctype.h>
+
+#include <cassert>
+#include <iterator>
+#include <memory>
+#include <set>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+
+namespace testing {
 // Input to a parameterized test name generator, describing a test parameter.
 // Consists of the parameter value and the integer parameter index.
 template <class ParamType>
@@ -11129,13 +10623,14 @@
 namespace internal {
 
 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
-//
+// Utility Functions
+
 // Outputs a message explaining invalid registration of different
-// fixture class for the same test case. This may happen when
+// fixture class for the same test suite. This may happen when
 // TEST_P macro is used to define two tests with the same name
 // but in different namespaces.
-GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
-                                          CodeLocation code_location);
+GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
+                                           CodeLocation code_location);
 
 template <typename> class ParamGeneratorInterface;
 template <typename> class ParamGenerator;
@@ -11210,7 +10705,7 @@
  private:
   friend class ParamGenerator<T>;
   explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
-  scoped_ptr<ParamIteratorInterface<T> > impl_;
+  std::unique_ptr<ParamIteratorInterface<T> > impl_;
 };
 
 // ParamGeneratorInterface<T> is the binary interface to access generators
@@ -11249,7 +10744,7 @@
   iterator end() const { return iterator(impl_->End()); }
 
  private:
-  linked_ptr<const ParamGeneratorInterface<T> > impl_;
+  std::shared_ptr<const ParamGeneratorInterface<T> > impl_;
 };
 
 // Generates values from a range of two comparable values. Can be used to
@@ -11262,12 +10757,12 @@
   RangeGenerator(T begin, T end, IncrementT step)
       : begin_(begin), end_(end),
         step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
-  virtual ~RangeGenerator() {}
+  ~RangeGenerator() override {}
 
-  virtual ParamIteratorInterface<T>* Begin() const {
+  ParamIteratorInterface<T>* Begin() const override {
     return new Iterator(this, begin_, 0, step_);
   }
-  virtual ParamIteratorInterface<T>* End() const {
+  ParamIteratorInterface<T>* End() const override {
     return new Iterator(this, end_, end_index_, step_);
   }
 
@@ -11277,20 +10772,20 @@
     Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
              IncrementT step)
         : base_(base), value_(value), index_(index), step_(step) {}
-    virtual ~Iterator() {}
+    ~Iterator() override {}
 
-    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+    const ParamGeneratorInterface<T>* BaseGenerator() const override {
       return base_;
     }
-    virtual void Advance() {
+    void Advance() override {
       value_ = static_cast<T>(value_ + step_);
       index_++;
     }
-    virtual ParamIteratorInterface<T>* Clone() const {
+    ParamIteratorInterface<T>* Clone() const override {
       return new Iterator(*this);
     }
-    virtual const T* Current() const { return &value_; }
-    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+    const T* Current() const override { return &value_; }
+    bool Equals(const ParamIteratorInterface<T>& other) const override {
       // Having the same base generator guarantees that the other
       // iterator is of the same type and we can downcast.
       GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
@@ -11347,12 +10842,12 @@
   template <typename ForwardIterator>
   ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
       : container_(begin, end) {}
-  virtual ~ValuesInIteratorRangeGenerator() {}
+  ~ValuesInIteratorRangeGenerator() override {}
 
-  virtual ParamIteratorInterface<T>* Begin() const {
+  ParamIteratorInterface<T>* Begin() const override {
     return new Iterator(this, container_.begin());
   }
-  virtual ParamIteratorInterface<T>* End() const {
+  ParamIteratorInterface<T>* End() const override {
     return new Iterator(this, container_.end());
   }
 
@@ -11364,16 +10859,16 @@
     Iterator(const ParamGeneratorInterface<T>* base,
              typename ContainerType::const_iterator iterator)
         : base_(base), iterator_(iterator) {}
-    virtual ~Iterator() {}
+    ~Iterator() override {}
 
-    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+    const ParamGeneratorInterface<T>* BaseGenerator() const override {
       return base_;
     }
-    virtual void Advance() {
+    void Advance() override {
       ++iterator_;
       value_.reset();
     }
-    virtual ParamIteratorInterface<T>* Clone() const {
+    ParamIteratorInterface<T>* Clone() const override {
       return new Iterator(*this);
     }
     // We need to use cached value referenced by iterator_ because *iterator_
@@ -11383,12 +10878,11 @@
     // can advance iterator_ beyond the end of the range, and we cannot
     // detect that fact. The client code, on the other hand, is
     // responsible for not calling Current() on an out-of-range iterator.
-    virtual const T* Current() const {
-      if (value_.get() == NULL)
-        value_.reset(new T(*iterator_));
+    const T* Current() const override {
+      if (value_.get() == nullptr) value_.reset(new T(*iterator_));
       return value_.get();
     }
-    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+    bool Equals(const ParamIteratorInterface<T>& other) const override {
       // Having the same base generator guarantees that the other
       // iterator is of the same type and we can downcast.
       GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
@@ -11411,9 +10905,9 @@
     // A cached value of *iterator_. We keep it here to allow access by
     // pointer in the wrapping iterator's operator->().
     // value_ needs to be mutable to be accessed in Current().
-    // Use of scoped_ptr helps manage cached value's lifetime,
+    // Use of std::unique_ptr helps manage cached value's lifetime,
     // which is bound by the lifespan of the iterator itself.
-    mutable scoped_ptr<const T> value_;
+    mutable std::unique_ptr<const T> value_;
   };  // class ValuesInIteratorRangeGenerator::Iterator
 
   // No implementation - assignment is unsupported.
@@ -11433,25 +10927,12 @@
   return name_stream.GetString();
 }
 
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
-//
-// Parameterized test name overload helpers, which help the
-// INSTANTIATE_TEST_CASE_P macro choose between the default parameterized
-// test name generator and user param name generator.
-template <class ParamType, class ParamNameGenFunctor>
-ParamNameGenFunctor GetParamNameGen(ParamNameGenFunctor func) {
-  return func;
+template <typename T = int>
+void TestNotEmpty() {
+  static_assert(sizeof(T) == 0, "Empty arguments are not allowed.");
 }
-
-template <class ParamType>
-struct ParamNameGenFunc {
-  typedef std::string Type(const TestParamInfo<ParamType>&);
-};
-
-template <class ParamType>
-typename ParamNameGenFunc<ParamType>::Type *GetParamNameGen() {
-  return DefaultParamName;
-}
+template <typename T = int>
+void TestNotEmpty(const T&) {}
 
 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
 //
@@ -11463,7 +10944,7 @@
   typedef typename TestClass::ParamType ParamType;
   explicit ParameterizedTestFactory(ParamType parameter) :
       parameter_(parameter) {}
-  virtual Test* CreateTest() {
+  Test* CreateTest() override {
     TestClass::SetParam(&parameter_);
     return new TestClass();
   }
@@ -11491,19 +10972,19 @@
 // TestMetaFactory creates test factories for passing into
 // MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
 // ownership of test factory pointer, same factory object cannot be passed
-// into that method twice. But ParameterizedTestCaseInfo is going to call
+// into that method twice. But ParameterizedTestSuiteInfo is going to call
 // it for each Test/Parameter value combination. Thus it needs meta factory
 // creator class.
-template <class TestCase>
+template <class TestSuite>
 class TestMetaFactory
-    : public TestMetaFactoryBase<typename TestCase::ParamType> {
+    : public TestMetaFactoryBase<typename TestSuite::ParamType> {
  public:
-  typedef typename TestCase::ParamType ParamType;
+  using ParamType = typename TestSuite::ParamType;
 
   TestMetaFactory() {}
 
-  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
-    return new ParameterizedTestFactory<TestCase>(parameter);
+  TestFactoryBase* CreateTestFactory(ParamType parameter) override {
+    return new ParameterizedTestFactory<TestSuite>(parameter);
   }
 
  private:
@@ -11512,107 +10993,106 @@
 
 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
 //
-// ParameterizedTestCaseInfoBase is a generic interface
-// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
+// ParameterizedTestSuiteInfoBase is a generic interface
+// to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase
 // accumulates test information provided by TEST_P macro invocations
-// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
+// and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations
 // and uses that information to register all resulting test instances
-// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
-// a collection of pointers to the ParameterizedTestCaseInfo objects
+// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
+// a collection of pointers to the ParameterizedTestSuiteInfo objects
 // and calls RegisterTests() on each of them when asked.
-class ParameterizedTestCaseInfoBase {
+class ParameterizedTestSuiteInfoBase {
  public:
-  virtual ~ParameterizedTestCaseInfoBase() {}
+  virtual ~ParameterizedTestSuiteInfoBase() {}
 
-  // Base part of test case name for display purposes.
-  virtual const string& GetTestCaseName() const = 0;
+  // Base part of test suite name for display purposes.
+  virtual const std::string& GetTestSuiteName() const = 0;
   // Test case id to verify identity.
-  virtual TypeId GetTestCaseTypeId() const = 0;
+  virtual TypeId GetTestSuiteTypeId() const = 0;
   // UnitTest class invokes this method to register tests in this
-  // test case right before running them in RUN_ALL_TESTS macro.
+  // test suite right before running them in RUN_ALL_TESTS macro.
   // This method should not be called more then once on any single
-  // instance of a ParameterizedTestCaseInfoBase derived class.
+  // instance of a ParameterizedTestSuiteInfoBase derived class.
   virtual void RegisterTests() = 0;
 
  protected:
-  ParameterizedTestCaseInfoBase() {}
+  ParameterizedTestSuiteInfoBase() {}
 
  private:
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase);
 };
 
 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
 //
-// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
-// macro invocations for a particular test case and generators
-// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
-// test case. It registers tests with all values generated by all
+// ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P
+// macro invocations for a particular test suite and generators
+// obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that
+// test suite. It registers tests with all values generated by all
 // generators when asked.
-template <class TestCase>
-class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
+template <class TestSuite>
+class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
  public:
   // ParamType and GeneratorCreationFunc are private types but are required
   // for declarations of public methods AddTestPattern() and
-  // AddTestCaseInstantiation().
-  typedef typename TestCase::ParamType ParamType;
+  // AddTestSuiteInstantiation().
+  using ParamType = typename TestSuite::ParamType;
   // A function that returns an instance of appropriate generator type.
   typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
-  typedef typename ParamNameGenFunc<ParamType>::Type ParamNameGeneratorFunc;
+  using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
 
-  explicit ParameterizedTestCaseInfo(
-      const char* name, CodeLocation code_location)
-      : test_case_name_(name), code_location_(code_location) {}
+  explicit ParameterizedTestSuiteInfo(const char* name,
+                                      CodeLocation code_location)
+      : test_suite_name_(name), code_location_(code_location) {}
 
   // Test case base name for display purposes.
-  virtual const string& GetTestCaseName() const { return test_case_name_; }
+  const std::string& GetTestSuiteName() const override {
+    return test_suite_name_;
+  }
   // Test case id to verify identity.
-  virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
+  TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }
   // TEST_P macro uses AddTestPattern() to record information
   // about a single test in a LocalTestInfo structure.
-  // test_case_name is the base name of the test case (without invocation
+  // test_suite_name is the base name of the test suite (without invocation
   // prefix). test_base_name is the name of an individual test without
   // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
-  // test case base name and DoBar is test base name.
-  void AddTestPattern(const char* test_case_name,
-                      const char* test_base_name,
+  // test suite base name and DoBar is test base name.
+  void AddTestPattern(const char* test_suite_name, const char* test_base_name,
                       TestMetaFactoryBase<ParamType>* meta_factory) {
-    tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
-                                                       test_base_name,
-                                                       meta_factory)));
+    tests_.push_back(std::shared_ptr<TestInfo>(
+        new TestInfo(test_suite_name, test_base_name, meta_factory)));
   }
-  // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
+  // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
   // about a generator.
-  int AddTestCaseInstantiation(const string& instantiation_name,
-                               GeneratorCreationFunc* func,
-                               ParamNameGeneratorFunc* name_func,
-                               const char* file,
-                               int line) {
+  int AddTestSuiteInstantiation(const std::string& instantiation_name,
+                                GeneratorCreationFunc* func,
+                                ParamNameGeneratorFunc* name_func,
+                                const char* file, int line) {
     instantiations_.push_back(
         InstantiationInfo(instantiation_name, func, name_func, file, line));
     return 0;  // Return value used only to run this method in namespace scope.
   }
-  // UnitTest class invokes this method to register tests in this test case
-  // test cases right before running tests in RUN_ALL_TESTS macro.
+  // UnitTest class invokes this method to register tests in this test suite
+  // test suites right before running tests in RUN_ALL_TESTS macro.
   // This method should not be called more then once on any single
-  // instance of a ParameterizedTestCaseInfoBase derived class.
+  // instance of a ParameterizedTestSuiteInfoBase derived class.
   // UnitTest has a guard to prevent from calling this method more then once.
-  virtual void RegisterTests() {
+  void RegisterTests() override {
     for (typename TestInfoContainer::iterator test_it = tests_.begin();
          test_it != tests_.end(); ++test_it) {
-      linked_ptr<TestInfo> test_info = *test_it;
+      std::shared_ptr<TestInfo> test_info = *test_it;
       for (typename InstantiationContainer::iterator gen_it =
                instantiations_.begin(); gen_it != instantiations_.end();
                ++gen_it) {
-        const string& instantiation_name = gen_it->name;
+        const std::string& instantiation_name = gen_it->name;
         ParamGenerator<ParamType> generator((*gen_it->generator)());
         ParamNameGeneratorFunc* name_func = gen_it->name_func;
         const char* file = gen_it->file;
         int line = gen_it->line;
 
-        string test_case_name;
+        std::string test_suite_name;
         if ( !instantiation_name.empty() )
-          test_case_name = instantiation_name + "/";
-        test_case_name += test_info->test_case_base_name;
+          test_suite_name = instantiation_name + "/";
+        test_suite_name += test_info->test_suite_base_name;
 
         size_t i = 0;
         std::set<std::string> test_param_names;
@@ -11637,37 +11117,34 @@
 
           test_name_stream << test_info->test_base_name << "/" << param_name;
           MakeAndRegisterTestInfo(
-              test_case_name.c_str(),
-              test_name_stream.GetString().c_str(),
-              NULL,  // No type parameter.
-              PrintToString(*param_it).c_str(),
-              code_location_,
-              GetTestCaseTypeId(),
-              TestCase::SetUpTestCase,
-              TestCase::TearDownTestCase,
+              test_suite_name.c_str(), test_name_stream.GetString().c_str(),
+              nullptr,  // No type parameter.
+              PrintToString(*param_it).c_str(), code_location_,
+              GetTestSuiteTypeId(),
+              SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(),
+              SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(),
               test_info->test_meta_factory->CreateTestFactory(*param_it));
         }  // for param_it
       }  // for gen_it
     }  // for test_it
-  }  // RegisterTests
+  }    // RegisterTests
 
  private:
   // LocalTestInfo structure keeps information about a single test registered
   // with TEST_P macro.
   struct TestInfo {
-    TestInfo(const char* a_test_case_base_name,
-             const char* a_test_base_name,
-             TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
-        test_case_base_name(a_test_case_base_name),
-        test_base_name(a_test_base_name),
-        test_meta_factory(a_test_meta_factory) {}
+    TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
+             TestMetaFactoryBase<ParamType>* a_test_meta_factory)
+        : test_suite_base_name(a_test_suite_base_name),
+          test_base_name(a_test_base_name),
+          test_meta_factory(a_test_meta_factory) {}
 
-    const string test_case_base_name;
-    const string test_base_name;
-    const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
+    const std::string test_suite_base_name;
+    const std::string test_base_name;
+    const std::unique_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
   };
-  typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
-  // Records data received from INSTANTIATE_TEST_CASE_P macros:
+  using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo> >;
+  // Records data received from INSTANTIATE_TEST_SUITE_P macros:
   //  <Instantiation name, Sequence generator creation function,
   //     Name generator function, Source file, Source line>
   struct InstantiationInfo {
@@ -11704,5241 +11181,264 @@
     return true;
   }
 
-  const string test_case_name_;
+  const std::string test_suite_name_;
   CodeLocation code_location_;
   TestInfoContainer tests_;
   InstantiationContainer instantiations_;
 
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
-};  // class ParameterizedTestCaseInfo
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfo);
+};  // class ParameterizedTestSuiteInfo
+
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+template <class TestCase>
+using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
 //
-// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
-// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
-// macros use it to locate their corresponding ParameterizedTestCaseInfo
-// descriptors.
-class ParameterizedTestCaseRegistry {
+// ParameterizedTestSuiteRegistry contains a map of
+// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
+// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
+// ParameterizedTestSuiteInfo descriptors.
+class ParameterizedTestSuiteRegistry {
  public:
-  ParameterizedTestCaseRegistry() {}
-  ~ParameterizedTestCaseRegistry() {
-    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
-         it != test_case_infos_.end(); ++it) {
-      delete *it;
+  ParameterizedTestSuiteRegistry() {}
+  ~ParameterizedTestSuiteRegistry() {
+    for (auto& test_suite_info : test_suite_infos_) {
+      delete test_suite_info;
     }
   }
 
   // Looks up or creates and returns a structure containing information about
-  // tests and instantiations of a particular test case.
-  template <class TestCase>
-  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
-      const char* test_case_name,
-      CodeLocation code_location) {
-    ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
-    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
-         it != test_case_infos_.end(); ++it) {
-      if ((*it)->GetTestCaseName() == test_case_name) {
-        if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
+  // tests and instantiations of a particular test suite.
+  template <class TestSuite>
+  ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
+      const char* test_suite_name, CodeLocation code_location) {
+    ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
+    for (auto& test_suite_info : test_suite_infos_) {
+      if (test_suite_info->GetTestSuiteName() == test_suite_name) {
+        if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
           // Complain about incorrect usage of Google Test facilities
           // and terminate the program since we cannot guaranty correct
-          // test case setup and tear-down in this case.
-          ReportInvalidTestCaseType(test_case_name, code_location);
+          // test suite setup and tear-down in this case.
+          ReportInvalidTestSuiteType(test_suite_name, code_location);
           posix::Abort();
         } else {
           // At this point we are sure that the object we found is of the same
           // type we are looking for, so we downcast it to that type
           // without further checks.
           typed_test_info = CheckedDowncastToActualType<
-              ParameterizedTestCaseInfo<TestCase> >(*it);
+              ParameterizedTestSuiteInfo<TestSuite> >(test_suite_info);
         }
         break;
       }
     }
-    if (typed_test_info == NULL) {
-      typed_test_info = new ParameterizedTestCaseInfo<TestCase>(
-          test_case_name, code_location);
-      test_case_infos_.push_back(typed_test_info);
+    if (typed_test_info == nullptr) {
+      typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
+          test_suite_name, code_location);
+      test_suite_infos_.push_back(typed_test_info);
     }
     return typed_test_info;
   }
   void RegisterTests() {
-    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
-         it != test_case_infos_.end(); ++it) {
-      (*it)->RegisterTests();
+    for (auto& test_suite_info : test_suite_infos_) {
+      test_suite_info->RegisterTests();
     }
   }
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+  template <class TestCase>
+  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
+      const char* test_case_name, CodeLocation code_location) {
+    return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
+  }
+
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
  private:
-  typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
+  using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
 
-  TestCaseInfoContainer test_case_infos_;
+  TestSuiteInfoContainer test_suite_infos_;
 
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry);
 };
 
 }  // namespace internal
-}  // namespace testing
-
-#endif  //  GTEST_HAS_PARAM_TEST
-
-#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
-// This file was GENERATED by command:
-//     pump.py gtest-param-util-generated.h.pump
-// DO NOT EDIT BY HAND!!!
-
-// Copyright 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: vladl@google.com (Vlad Losev)
-
-// Type and function utilities for implementing parameterized tests.
-// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
-//
-// Currently Google Test supports at most 50 arguments in Values,
-// and at most 10 arguments in Combine. Please contact
-// googletestframework@googlegroups.com if you need more.
-// Please note that the number of arguments to Combine is limited
-// by the maximum arity of the implementation of tuple which is
-// currently set at 10.
-
-#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
-#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
-
-// scripts/fuse_gtest.py depends on gtest's own header being #included
-// *unconditionally*.  Therefore these #includes cannot be moved
-// inside #if GTEST_HAS_PARAM_TEST.
-
-#if GTEST_HAS_PARAM_TEST
-
-namespace testing {
 
 // Forward declarations of ValuesIn(), which is implemented in
 // include/gtest/gtest-param-test.h.
-template <typename ForwardIterator>
-internal::ParamGenerator<
-  typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
-ValuesIn(ForwardIterator begin, ForwardIterator end);
-
-template <typename T, size_t N>
-internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
-
 template <class Container>
 internal::ParamGenerator<typename Container::value_type> ValuesIn(
     const Container& container);
 
 namespace internal {
-
 // Used in the Values() function to provide polymorphic capabilities.
-template <typename T1>
-class ValueArray1 {
+
+template <typename... Ts>
+class ValueArray {
  public:
-  explicit ValueArray1(T1 v1) : v1_(v1) {}
+  ValueArray(Ts... v) : v_{std::move(v)...} {}
 
   template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_)};
-    return ValuesIn(array);
+  operator ParamGenerator<T>() const {  // NOLINT
+    return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
   }
 
  private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray1& other);
+  template <typename T, size_t... I>
+  std::vector<T> MakeVector(IndexSequence<I...>) const {
+    return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
+  }
 
-  const T1 v1_;
+  FlatTuple<Ts...> v_;
 };
 
-template <typename T1, typename T2>
-class ValueArray2 {
+template <typename... T>
+class CartesianProductGenerator
+    : public ParamGeneratorInterface<::std::tuple<T...>> {
  public:
-  ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {}
+  typedef ::std::tuple<T...> ParamType;
 
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_)};
-    return ValuesIn(array);
+  CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)
+      : generators_(g) {}
+  ~CartesianProductGenerator() override {}
+
+  ParamIteratorInterface<ParamType>* Begin() const override {
+    return new Iterator(this, generators_, false);
+  }
+  ParamIteratorInterface<ParamType>* End() const override {
+    return new Iterator(this, generators_, true);
   }
 
  private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray2& other);
-
-  const T1 v1_;
-  const T2 v2_;
-};
-
-template <typename T1, typename T2, typename T3>
-class ValueArray3 {
- public:
-  ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray3& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4>
-class ValueArray4 {
- public:
-  ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3),
-      v4_(v4) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray4& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-class ValueArray5 {
- public:
-  ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3),
-      v4_(v4), v5_(v5) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray5& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6>
-class ValueArray6 {
- public:
-  ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2),
-      v3_(v3), v4_(v4), v5_(v5), v6_(v6) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray6& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7>
-class ValueArray7 {
- public:
-  ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1),
-      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray7& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8>
-class ValueArray8 {
- public:
-  ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
-      T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
-      v8_(v8) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray8& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9>
-class ValueArray9 {
- public:
-  ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
-      T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
-      v8_(v8), v9_(v9) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray9& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10>
-class ValueArray10 {
- public:
-  ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
-      v8_(v8), v9_(v9), v10_(v10) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray10& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11>
-class ValueArray11 {
- public:
-  ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
-      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray11& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12>
-class ValueArray12 {
- public:
-  ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
-      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray12& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13>
-class ValueArray13 {
- public:
-  ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
-      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
-      v12_(v12), v13_(v13) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray13& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14>
-class ValueArray14 {
- public:
-  ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3),
-      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
-      v11_(v11), v12_(v12), v13_(v13), v14_(v14) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray14& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15>
-class ValueArray15 {
- public:
-  ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2),
-      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
-      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray15& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16>
-class ValueArray16 {
- public:
-  ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1),
-      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
-      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
-      v16_(v16) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray16& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17>
-class ValueArray17 {
- public:
-  ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
-      T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
-      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
-      v15_(v15), v16_(v16), v17_(v17) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray17& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18>
-class ValueArray18 {
- public:
-  ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
-      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
-      v15_(v15), v16_(v16), v17_(v17), v18_(v18) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray18& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19>
-class ValueArray19 {
- public:
-  ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
-      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
-      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray19& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20>
-class ValueArray20 {
- public:
-  ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
-      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
-      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
-      v19_(v19), v20_(v20) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray20& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21>
-class ValueArray21 {
- public:
-  ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
-      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
-      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
-      v18_(v18), v19_(v19), v20_(v20), v21_(v21) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray21& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22>
-class ValueArray22 {
- public:
-  ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3),
-      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
-      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
-      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray22& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23>
-class ValueArray23 {
- public:
-  ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2),
-      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
-      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
-      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
-      v23_(v23) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray23& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24>
-class ValueArray24 {
- public:
-  ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1),
-      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
-      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
-      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
-      v22_(v22), v23_(v23), v24_(v24) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray24& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25>
-class ValueArray25 {
- public:
-  ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
-      T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
-      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
-      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
-      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray25& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26>
-class ValueArray26 {
- public:
-  ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
-      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
-      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
-      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray26& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27>
-class ValueArray27 {
- public:
-  ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
-      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
-      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
-      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
-      v26_(v26), v27_(v27) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray27& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28>
-class ValueArray28 {
- public:
-  ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
-      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
-      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
-      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
-      v25_(v25), v26_(v26), v27_(v27), v28_(v28) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray28& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29>
-class ValueArray29 {
- public:
-  ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
-      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
-      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
-      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
-      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray29& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30>
-class ValueArray30 {
- public:
-  ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3),
-      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
-      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
-      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
-      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
-      v29_(v29), v30_(v30) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray30& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31>
-class ValueArray31 {
- public:
-  ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2),
-      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
-      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
-      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
-      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
-      v29_(v29), v30_(v30), v31_(v31) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray31& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32>
-class ValueArray32 {
- public:
-  ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1),
-      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
-      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
-      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
-      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
-      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray32& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33>
-class ValueArray33 {
- public:
-  ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
-      T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
-      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
-      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
-      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
-      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
-      v33_(v33) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray33& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34>
-class ValueArray34 {
- public:
-  ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
-      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
-      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
-      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
-      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
-      v33_(v33), v34_(v34) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray34& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35>
-class ValueArray35 {
- public:
-  ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
-      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
-      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
-      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
-      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
-      v32_(v32), v33_(v33), v34_(v34), v35_(v35) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray35& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36>
-class ValueArray36 {
- public:
-  ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
-      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
-      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
-      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
-      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
-      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray36& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37>
-class ValueArray37 {
- public:
-  ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
-      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
-      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
-      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
-      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
-      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
-      v36_(v36), v37_(v37) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray37& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38>
-class ValueArray38 {
- public:
-  ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3),
-      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
-      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
-      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
-      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
-      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
-      v35_(v35), v36_(v36), v37_(v37), v38_(v38) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray38& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-  const T38 v38_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39>
-class ValueArray39 {
- public:
-  ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2),
-      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
-      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
-      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
-      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
-      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
-      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
-        static_cast<T>(v39_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray39& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-  const T38 v38_;
-  const T39 v39_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40>
-class ValueArray40 {
- public:
-  ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1),
-      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
-      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
-      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
-      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
-      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
-      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
-      v40_(v40) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
-        static_cast<T>(v39_), static_cast<T>(v40_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray40& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-  const T38 v38_;
-  const T39 v39_;
-  const T40 v40_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41>
-class ValueArray41 {
- public:
-  ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
-      T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
-      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
-      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
-      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
-      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
-      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
-      v39_(v39), v40_(v40), v41_(v41) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
-        static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray41& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-  const T38 v38_;
-  const T39 v39_;
-  const T40 v40_;
-  const T41 v41_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42>
-class ValueArray42 {
- public:
-  ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
-      T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
-      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
-      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
-      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
-      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
-      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
-      v39_(v39), v40_(v40), v41_(v41), v42_(v42) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
-        static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
-        static_cast<T>(v42_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray42& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-  const T38 v38_;
-  const T39 v39_;
-  const T40 v40_;
-  const T41 v41_;
-  const T42 v42_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43>
-class ValueArray43 {
- public:
-  ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
-      T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
-      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
-      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
-      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
-      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
-      v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37),
-      v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
-        static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
-        static_cast<T>(v42_), static_cast<T>(v43_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray43& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-  const T38 v38_;
-  const T39 v39_;
-  const T40 v40_;
-  const T41 v41_;
-  const T42 v42_;
-  const T43 v43_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44>
-class ValueArray44 {
- public:
-  ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
-      T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
-      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
-      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
-      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
-      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
-      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36),
-      v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42),
-      v43_(v43), v44_(v44) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
-        static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
-        static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray44& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-  const T38 v38_;
-  const T39 v39_;
-  const T40 v40_;
-  const T41 v41_;
-  const T42 v42_;
-  const T43 v43_;
-  const T44 v44_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44, typename T45>
-class ValueArray45 {
- public:
-  ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
-      T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
-      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
-      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
-      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
-      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
-      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
-      v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41),
-      v42_(v42), v43_(v43), v44_(v44), v45_(v45) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
-        static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
-        static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
-        static_cast<T>(v45_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray45& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-  const T38 v38_;
-  const T39 v39_;
-  const T40 v40_;
-  const T41 v41_;
-  const T42 v42_;
-  const T43 v43_;
-  const T44 v44_;
-  const T45 v45_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44, typename T45,
-    typename T46>
-class ValueArray46 {
- public:
-  ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
-      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3),
-      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
-      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
-      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
-      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
-      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
-      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
-      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
-        static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
-        static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
-        static_cast<T>(v45_), static_cast<T>(v46_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray46& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-  const T38 v38_;
-  const T39 v39_;
-  const T40 v40_;
-  const T41 v41_;
-  const T42 v42_;
-  const T43 v43_;
-  const T44 v44_;
-  const T45 v45_;
-  const T46 v46_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44, typename T45,
-    typename T46, typename T47>
-class ValueArray47 {
- public:
-  ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
-      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2),
-      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
-      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
-      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
-      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
-      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
-      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
-      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46),
-      v47_(v47) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
-        static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
-        static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
-        static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray47& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-  const T38 v38_;
-  const T39 v39_;
-  const T40 v40_;
-  const T41 v41_;
-  const T42 v42_;
-  const T43 v43_;
-  const T44 v44_;
-  const T45 v45_;
-  const T46 v46_;
-  const T47 v47_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44, typename T45,
-    typename T46, typename T47, typename T48>
-class ValueArray48 {
- public:
-  ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
-      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1),
-      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
-      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
-      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
-      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
-      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
-      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
-      v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45),
-      v46_(v46), v47_(v47), v48_(v48) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
-        static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
-        static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
-        static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_),
-        static_cast<T>(v48_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray48& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-  const T38 v38_;
-  const T39 v39_;
-  const T40 v40_;
-  const T41 v41_;
-  const T42 v42_;
-  const T43 v43_;
-  const T44 v44_;
-  const T45 v45_;
-  const T46 v46_;
-  const T47 v47_;
-  const T48 v48_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44, typename T45,
-    typename T46, typename T47, typename T48, typename T49>
-class ValueArray49 {
- public:
-  ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
-      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48,
-      T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
-      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
-      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
-      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
-      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
-      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
-      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
-      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
-        static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
-        static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
-        static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_),
-        static_cast<T>(v48_), static_cast<T>(v49_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray49& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-  const T38 v38_;
-  const T39 v39_;
-  const T40 v40_;
-  const T41 v41_;
-  const T42 v42_;
-  const T43 v43_;
-  const T44 v44_;
-  const T45 v45_;
-  const T46 v46_;
-  const T47 v47_;
-  const T48 v48_;
-  const T49 v49_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44, typename T45,
-    typename T46, typename T47, typename T48, typename T49, typename T50>
-class ValueArray50 {
- public:
-  ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
-      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49,
-      T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
-      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
-      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
-      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
-      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
-      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
-      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
-      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {}
-
-  template <typename T>
-  operator ParamGenerator<T>() const {
-    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
-        static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
-        static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
-        static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
-        static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
-        static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
-        static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
-        static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
-        static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
-        static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
-        static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
-        static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
-        static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
-        static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
-        static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
-        static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_),
-        static_cast<T>(v48_), static_cast<T>(v49_), static_cast<T>(v50_)};
-    return ValuesIn(array);
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const ValueArray50& other);
-
-  const T1 v1_;
-  const T2 v2_;
-  const T3 v3_;
-  const T4 v4_;
-  const T5 v5_;
-  const T6 v6_;
-  const T7 v7_;
-  const T8 v8_;
-  const T9 v9_;
-  const T10 v10_;
-  const T11 v11_;
-  const T12 v12_;
-  const T13 v13_;
-  const T14 v14_;
-  const T15 v15_;
-  const T16 v16_;
-  const T17 v17_;
-  const T18 v18_;
-  const T19 v19_;
-  const T20 v20_;
-  const T21 v21_;
-  const T22 v22_;
-  const T23 v23_;
-  const T24 v24_;
-  const T25 v25_;
-  const T26 v26_;
-  const T27 v27_;
-  const T28 v28_;
-  const T29 v29_;
-  const T30 v30_;
-  const T31 v31_;
-  const T32 v32_;
-  const T33 v33_;
-  const T34 v34_;
-  const T35 v35_;
-  const T36 v36_;
-  const T37 v37_;
-  const T38 v38_;
-  const T39 v39_;
-  const T40 v40_;
-  const T41 v41_;
-  const T42 v42_;
-  const T43 v43_;
-  const T44 v44_;
-  const T45 v45_;
-  const T46 v46_;
-  const T47 v47_;
-  const T48 v48_;
-  const T49 v49_;
-  const T50 v50_;
-};
-
-# if GTEST_HAS_COMBINE
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
-//
-// Generates values from the Cartesian product of values produced
-// by the argument generators.
-//
-template <typename T1, typename T2>
-class CartesianProductGenerator2
-    : public ParamGeneratorInterface< ::testing::tuple<T1, T2> > {
- public:
-  typedef ::testing::tuple<T1, T2> ParamType;
-
-  CartesianProductGenerator2(const ParamGenerator<T1>& g1,
-      const ParamGenerator<T2>& g2)
-      : g1_(g1), g2_(g2) {}
-  virtual ~CartesianProductGenerator2() {}
-
-  virtual ParamIteratorInterface<ParamType>* Begin() const {
-    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin());
-  }
-  virtual ParamIteratorInterface<ParamType>* End() const {
-    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end());
-  }
-
- private:
-  class Iterator : public ParamIteratorInterface<ParamType> {
+  template <class I>
+  class IteratorImpl;
+  template <size_t... I>
+  class IteratorImpl<IndexSequence<I...>>
+      : public ParamIteratorInterface<ParamType> {
    public:
-    Iterator(const ParamGeneratorInterface<ParamType>* base,
-      const ParamGenerator<T1>& g1,
-      const typename ParamGenerator<T1>::iterator& current1,
-      const ParamGenerator<T2>& g2,
-      const typename ParamGenerator<T2>::iterator& current2)
+    IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
+             const std::tuple<ParamGenerator<T>...>& generators, bool is_end)
         : base_(base),
-          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
-          begin2_(g2.begin()), end2_(g2.end()), current2_(current2)    {
+          begin_(std::get<I>(generators).begin()...),
+          end_(std::get<I>(generators).end()...),
+          current_(is_end ? end_ : begin_) {
       ComputeCurrentValue();
     }
-    virtual ~Iterator() {}
+    ~IteratorImpl() override {}
 
-    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+    const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {
       return base_;
     }
     // Advance should not be called on beyond-of-range iterators
     // so no component iterators must be beyond end of range, either.
-    virtual void Advance() {
+    void Advance() override {
       assert(!AtEnd());
-      ++current2_;
-      if (current2_ == end2_) {
-        current2_ = begin2_;
-        ++current1_;
-      }
+      // Advance the last iterator.
+      ++std::get<sizeof...(T) - 1>(current_);
+      // if that reaches end, propagate that up.
+      AdvanceIfEnd<sizeof...(T) - 1>();
       ComputeCurrentValue();
     }
-    virtual ParamIteratorInterface<ParamType>* Clone() const {
-      return new Iterator(*this);
+    ParamIteratorInterface<ParamType>* Clone() const override {
+      return new IteratorImpl(*this);
     }
-    virtual const ParamType* Current() const { return &current_value_; }
-    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+
+    const ParamType* Current() const override { return current_value_.get(); }
+
+    bool Equals(const ParamIteratorInterface<ParamType>& other) const override {
       // Having the same base generator guarantees that the other
       // iterator is of the same type and we can downcast.
       GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
           << "The program attempted to compare iterators "
           << "from different generators." << std::endl;
-      const Iterator* typed_other =
-          CheckedDowncastToActualType<const Iterator>(&other);
+      const IteratorImpl* typed_other =
+          CheckedDowncastToActualType<const IteratorImpl>(&other);
+
       // We must report iterators equal if they both point beyond their
       // respective ranges. That can happen in a variety of fashions,
       // so we have to consult AtEnd().
-      return (AtEnd() && typed_other->AtEnd()) ||
-         (
-          current1_ == typed_other->current1_ &&
-          current2_ == typed_other->current2_);
+      if (AtEnd() && typed_other->AtEnd()) return true;
+
+      bool same = true;
+      bool dummy[] = {
+          (same = same && std::get<I>(current_) ==
+                              std::get<I>(typed_other->current_))...};
+      (void)dummy;
+      return same;
     }
 
    private:
-    Iterator(const Iterator& other)
-        : base_(other.base_),
-        begin1_(other.begin1_),
-        end1_(other.end1_),
-        current1_(other.current1_),
-        begin2_(other.begin2_),
-        end2_(other.end2_),
-        current2_(other.current2_) {
-      ComputeCurrentValue();
+    template <size_t ThisI>
+    void AdvanceIfEnd() {
+      if (std::get<ThisI>(current_) != std::get<ThisI>(end_)) return;
+
+      bool last = ThisI == 0;
+      if (last) {
+        // We are done. Nothing else to propagate.
+        return;
+      }
+
+      constexpr size_t NextI = ThisI - (ThisI != 0);
+      std::get<ThisI>(current_) = std::get<ThisI>(begin_);
+      ++std::get<NextI>(current_);
+      AdvanceIfEnd<NextI>();
     }
 
     void ComputeCurrentValue() {
       if (!AtEnd())
-        current_value_ = ParamType(*current1_, *current2_);
+        current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);
     }
     bool AtEnd() const {
-      // We must report iterator past the end of the range when either of the
-      // component iterators has reached the end of its range.
-      return
-          current1_ == end1_ ||
-          current2_ == end2_;
+      bool at_end = false;
+      bool dummy[] = {
+          (at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...};
+      (void)dummy;
+      return at_end;
     }
 
-    // No implementation - assignment is unsupported.
-    void operator=(const Iterator& other);
-
     const ParamGeneratorInterface<ParamType>* const base_;
-    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
-    // current[i]_ is the actual traversing iterator.
-    const typename ParamGenerator<T1>::iterator begin1_;
-    const typename ParamGenerator<T1>::iterator end1_;
-    typename ParamGenerator<T1>::iterator current1_;
-    const typename ParamGenerator<T2>::iterator begin2_;
-    const typename ParamGenerator<T2>::iterator end2_;
-    typename ParamGenerator<T2>::iterator current2_;
-    ParamType current_value_;
-  };  // class CartesianProductGenerator2::Iterator
+    std::tuple<typename ParamGenerator<T>::iterator...> begin_;
+    std::tuple<typename ParamGenerator<T>::iterator...> end_;
+    std::tuple<typename ParamGenerator<T>::iterator...> current_;
+    std::shared_ptr<ParamType> current_value_;
+  };
 
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductGenerator2& other);
+  using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
 
-  const ParamGenerator<T1> g1_;
-  const ParamGenerator<T2> g2_;
-};  // class CartesianProductGenerator2
+  std::tuple<ParamGenerator<T>...> generators_;
+};
 
-
-template <typename T1, typename T2, typename T3>
-class CartesianProductGenerator3
-    : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3> > {
+template <class... Gen>
+class CartesianProductHolder {
  public:
-  typedef ::testing::tuple<T1, T2, T3> ParamType;
-
-  CartesianProductGenerator3(const ParamGenerator<T1>& g1,
-      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3)
-      : g1_(g1), g2_(g2), g3_(g3) {}
-  virtual ~CartesianProductGenerator3() {}
-
-  virtual ParamIteratorInterface<ParamType>* Begin() const {
-    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
-        g3_.begin());
-  }
-  virtual ParamIteratorInterface<ParamType>* End() const {
-    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end());
+  CartesianProductHolder(const Gen&... g) : generators_(g...) {}
+  template <typename... T>
+  operator ParamGenerator<::std::tuple<T...>>() const {
+    return ParamGenerator<::std::tuple<T...>>(
+        new CartesianProductGenerator<T...>(generators_));
   }
 
  private:
-  class Iterator : public ParamIteratorInterface<ParamType> {
-   public:
-    Iterator(const ParamGeneratorInterface<ParamType>* base,
-      const ParamGenerator<T1>& g1,
-      const typename ParamGenerator<T1>::iterator& current1,
-      const ParamGenerator<T2>& g2,
-      const typename ParamGenerator<T2>::iterator& current2,
-      const ParamGenerator<T3>& g3,
-      const typename ParamGenerator<T3>::iterator& current3)
-        : base_(base),
-          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
-          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
-          begin3_(g3.begin()), end3_(g3.end()), current3_(current3)    {
-      ComputeCurrentValue();
-    }
-    virtual ~Iterator() {}
-
-    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
-      return base_;
-    }
-    // Advance should not be called on beyond-of-range iterators
-    // so no component iterators must be beyond end of range, either.
-    virtual void Advance() {
-      assert(!AtEnd());
-      ++current3_;
-      if (current3_ == end3_) {
-        current3_ = begin3_;
-        ++current2_;
-      }
-      if (current2_ == end2_) {
-        current2_ = begin2_;
-        ++current1_;
-      }
-      ComputeCurrentValue();
-    }
-    virtual ParamIteratorInterface<ParamType>* Clone() const {
-      return new Iterator(*this);
-    }
-    virtual const ParamType* Current() const { return &current_value_; }
-    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
-      // Having the same base generator guarantees that the other
-      // iterator is of the same type and we can downcast.
-      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
-          << "The program attempted to compare iterators "
-          << "from different generators." << std::endl;
-      const Iterator* typed_other =
-          CheckedDowncastToActualType<const Iterator>(&other);
-      // We must report iterators equal if they both point beyond their
-      // respective ranges. That can happen in a variety of fashions,
-      // so we have to consult AtEnd().
-      return (AtEnd() && typed_other->AtEnd()) ||
-         (
-          current1_ == typed_other->current1_ &&
-          current2_ == typed_other->current2_ &&
-          current3_ == typed_other->current3_);
-    }
-
-   private:
-    Iterator(const Iterator& other)
-        : base_(other.base_),
-        begin1_(other.begin1_),
-        end1_(other.end1_),
-        current1_(other.current1_),
-        begin2_(other.begin2_),
-        end2_(other.end2_),
-        current2_(other.current2_),
-        begin3_(other.begin3_),
-        end3_(other.end3_),
-        current3_(other.current3_) {
-      ComputeCurrentValue();
-    }
-
-    void ComputeCurrentValue() {
-      if (!AtEnd())
-        current_value_ = ParamType(*current1_, *current2_, *current3_);
-    }
-    bool AtEnd() const {
-      // We must report iterator past the end of the range when either of the
-      // component iterators has reached the end of its range.
-      return
-          current1_ == end1_ ||
-          current2_ == end2_ ||
-          current3_ == end3_;
-    }
-
-    // No implementation - assignment is unsupported.
-    void operator=(const Iterator& other);
-
-    const ParamGeneratorInterface<ParamType>* const base_;
-    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
-    // current[i]_ is the actual traversing iterator.
-    const typename ParamGenerator<T1>::iterator begin1_;
-    const typename ParamGenerator<T1>::iterator end1_;
-    typename ParamGenerator<T1>::iterator current1_;
-    const typename ParamGenerator<T2>::iterator begin2_;
-    const typename ParamGenerator<T2>::iterator end2_;
-    typename ParamGenerator<T2>::iterator current2_;
-    const typename ParamGenerator<T3>::iterator begin3_;
-    const typename ParamGenerator<T3>::iterator end3_;
-    typename ParamGenerator<T3>::iterator current3_;
-    ParamType current_value_;
-  };  // class CartesianProductGenerator3::Iterator
-
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductGenerator3& other);
-
-  const ParamGenerator<T1> g1_;
-  const ParamGenerator<T2> g2_;
-  const ParamGenerator<T3> g3_;
-};  // class CartesianProductGenerator3
-
-
-template <typename T1, typename T2, typename T3, typename T4>
-class CartesianProductGenerator4
-    : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4> > {
- public:
-  typedef ::testing::tuple<T1, T2, T3, T4> ParamType;
-
-  CartesianProductGenerator4(const ParamGenerator<T1>& g1,
-      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
-      const ParamGenerator<T4>& g4)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
-  virtual ~CartesianProductGenerator4() {}
-
-  virtual ParamIteratorInterface<ParamType>* Begin() const {
-    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
-        g3_.begin(), g4_, g4_.begin());
-  }
-  virtual ParamIteratorInterface<ParamType>* End() const {
-    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
-        g4_, g4_.end());
-  }
-
- private:
-  class Iterator : public ParamIteratorInterface<ParamType> {
-   public:
-    Iterator(const ParamGeneratorInterface<ParamType>* base,
-      const ParamGenerator<T1>& g1,
-      const typename ParamGenerator<T1>::iterator& current1,
-      const ParamGenerator<T2>& g2,
-      const typename ParamGenerator<T2>::iterator& current2,
-      const ParamGenerator<T3>& g3,
-      const typename ParamGenerator<T3>::iterator& current3,
-      const ParamGenerator<T4>& g4,
-      const typename ParamGenerator<T4>::iterator& current4)
-        : base_(base),
-          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
-          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
-          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
-          begin4_(g4.begin()), end4_(g4.end()), current4_(current4)    {
-      ComputeCurrentValue();
-    }
-    virtual ~Iterator() {}
-
-    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
-      return base_;
-    }
-    // Advance should not be called on beyond-of-range iterators
-    // so no component iterators must be beyond end of range, either.
-    virtual void Advance() {
-      assert(!AtEnd());
-      ++current4_;
-      if (current4_ == end4_) {
-        current4_ = begin4_;
-        ++current3_;
-      }
-      if (current3_ == end3_) {
-        current3_ = begin3_;
-        ++current2_;
-      }
-      if (current2_ == end2_) {
-        current2_ = begin2_;
-        ++current1_;
-      }
-      ComputeCurrentValue();
-    }
-    virtual ParamIteratorInterface<ParamType>* Clone() const {
-      return new Iterator(*this);
-    }
-    virtual const ParamType* Current() const { return &current_value_; }
-    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
-      // Having the same base generator guarantees that the other
-      // iterator is of the same type and we can downcast.
-      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
-          << "The program attempted to compare iterators "
-          << "from different generators." << std::endl;
-      const Iterator* typed_other =
-          CheckedDowncastToActualType<const Iterator>(&other);
-      // We must report iterators equal if they both point beyond their
-      // respective ranges. That can happen in a variety of fashions,
-      // so we have to consult AtEnd().
-      return (AtEnd() && typed_other->AtEnd()) ||
-         (
-          current1_ == typed_other->current1_ &&
-          current2_ == typed_other->current2_ &&
-          current3_ == typed_other->current3_ &&
-          current4_ == typed_other->current4_);
-    }
-
-   private:
-    Iterator(const Iterator& other)
-        : base_(other.base_),
-        begin1_(other.begin1_),
-        end1_(other.end1_),
-        current1_(other.current1_),
-        begin2_(other.begin2_),
-        end2_(other.end2_),
-        current2_(other.current2_),
-        begin3_(other.begin3_),
-        end3_(other.end3_),
-        current3_(other.current3_),
-        begin4_(other.begin4_),
-        end4_(other.end4_),
-        current4_(other.current4_) {
-      ComputeCurrentValue();
-    }
-
-    void ComputeCurrentValue() {
-      if (!AtEnd())
-        current_value_ = ParamType(*current1_, *current2_, *current3_,
-            *current4_);
-    }
-    bool AtEnd() const {
-      // We must report iterator past the end of the range when either of the
-      // component iterators has reached the end of its range.
-      return
-          current1_ == end1_ ||
-          current2_ == end2_ ||
-          current3_ == end3_ ||
-          current4_ == end4_;
-    }
-
-    // No implementation - assignment is unsupported.
-    void operator=(const Iterator& other);
-
-    const ParamGeneratorInterface<ParamType>* const base_;
-    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
-    // current[i]_ is the actual traversing iterator.
-    const typename ParamGenerator<T1>::iterator begin1_;
-    const typename ParamGenerator<T1>::iterator end1_;
-    typename ParamGenerator<T1>::iterator current1_;
-    const typename ParamGenerator<T2>::iterator begin2_;
-    const typename ParamGenerator<T2>::iterator end2_;
-    typename ParamGenerator<T2>::iterator current2_;
-    const typename ParamGenerator<T3>::iterator begin3_;
-    const typename ParamGenerator<T3>::iterator end3_;
-    typename ParamGenerator<T3>::iterator current3_;
-    const typename ParamGenerator<T4>::iterator begin4_;
-    const typename ParamGenerator<T4>::iterator end4_;
-    typename ParamGenerator<T4>::iterator current4_;
-    ParamType current_value_;
-  };  // class CartesianProductGenerator4::Iterator
-
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductGenerator4& other);
-
-  const ParamGenerator<T1> g1_;
-  const ParamGenerator<T2> g2_;
-  const ParamGenerator<T3> g3_;
-  const ParamGenerator<T4> g4_;
-};  // class CartesianProductGenerator4
-
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-class CartesianProductGenerator5
-    : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5> > {
- public:
-  typedef ::testing::tuple<T1, T2, T3, T4, T5> ParamType;
-
-  CartesianProductGenerator5(const ParamGenerator<T1>& g1,
-      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
-      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
-  virtual ~CartesianProductGenerator5() {}
-
-  virtual ParamIteratorInterface<ParamType>* Begin() const {
-    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
-        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin());
-  }
-  virtual ParamIteratorInterface<ParamType>* End() const {
-    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
-        g4_, g4_.end(), g5_, g5_.end());
-  }
-
- private:
-  class Iterator : public ParamIteratorInterface<ParamType> {
-   public:
-    Iterator(const ParamGeneratorInterface<ParamType>* base,
-      const ParamGenerator<T1>& g1,
-      const typename ParamGenerator<T1>::iterator& current1,
-      const ParamGenerator<T2>& g2,
-      const typename ParamGenerator<T2>::iterator& current2,
-      const ParamGenerator<T3>& g3,
-      const typename ParamGenerator<T3>::iterator& current3,
-      const ParamGenerator<T4>& g4,
-      const typename ParamGenerator<T4>::iterator& current4,
-      const ParamGenerator<T5>& g5,
-      const typename ParamGenerator<T5>::iterator& current5)
-        : base_(base),
-          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
-          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
-          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
-          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
-          begin5_(g5.begin()), end5_(g5.end()), current5_(current5)    {
-      ComputeCurrentValue();
-    }
-    virtual ~Iterator() {}
-
-    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
-      return base_;
-    }
-    // Advance should not be called on beyond-of-range iterators
-    // so no component iterators must be beyond end of range, either.
-    virtual void Advance() {
-      assert(!AtEnd());
-      ++current5_;
-      if (current5_ == end5_) {
-        current5_ = begin5_;
-        ++current4_;
-      }
-      if (current4_ == end4_) {
-        current4_ = begin4_;
-        ++current3_;
-      }
-      if (current3_ == end3_) {
-        current3_ = begin3_;
-        ++current2_;
-      }
-      if (current2_ == end2_) {
-        current2_ = begin2_;
-        ++current1_;
-      }
-      ComputeCurrentValue();
-    }
-    virtual ParamIteratorInterface<ParamType>* Clone() const {
-      return new Iterator(*this);
-    }
-    virtual const ParamType* Current() const { return &current_value_; }
-    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
-      // Having the same base generator guarantees that the other
-      // iterator is of the same type and we can downcast.
-      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
-          << "The program attempted to compare iterators "
-          << "from different generators." << std::endl;
-      const Iterator* typed_other =
-          CheckedDowncastToActualType<const Iterator>(&other);
-      // We must report iterators equal if they both point beyond their
-      // respective ranges. That can happen in a variety of fashions,
-      // so we have to consult AtEnd().
-      return (AtEnd() && typed_other->AtEnd()) ||
-         (
-          current1_ == typed_other->current1_ &&
-          current2_ == typed_other->current2_ &&
-          current3_ == typed_other->current3_ &&
-          current4_ == typed_other->current4_ &&
-          current5_ == typed_other->current5_);
-    }
-
-   private:
-    Iterator(const Iterator& other)
-        : base_(other.base_),
-        begin1_(other.begin1_),
-        end1_(other.end1_),
-        current1_(other.current1_),
-        begin2_(other.begin2_),
-        end2_(other.end2_),
-        current2_(other.current2_),
-        begin3_(other.begin3_),
-        end3_(other.end3_),
-        current3_(other.current3_),
-        begin4_(other.begin4_),
-        end4_(other.end4_),
-        current4_(other.current4_),
-        begin5_(other.begin5_),
-        end5_(other.end5_),
-        current5_(other.current5_) {
-      ComputeCurrentValue();
-    }
-
-    void ComputeCurrentValue() {
-      if (!AtEnd())
-        current_value_ = ParamType(*current1_, *current2_, *current3_,
-            *current4_, *current5_);
-    }
-    bool AtEnd() const {
-      // We must report iterator past the end of the range when either of the
-      // component iterators has reached the end of its range.
-      return
-          current1_ == end1_ ||
-          current2_ == end2_ ||
-          current3_ == end3_ ||
-          current4_ == end4_ ||
-          current5_ == end5_;
-    }
-
-    // No implementation - assignment is unsupported.
-    void operator=(const Iterator& other);
-
-    const ParamGeneratorInterface<ParamType>* const base_;
-    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
-    // current[i]_ is the actual traversing iterator.
-    const typename ParamGenerator<T1>::iterator begin1_;
-    const typename ParamGenerator<T1>::iterator end1_;
-    typename ParamGenerator<T1>::iterator current1_;
-    const typename ParamGenerator<T2>::iterator begin2_;
-    const typename ParamGenerator<T2>::iterator end2_;
-    typename ParamGenerator<T2>::iterator current2_;
-    const typename ParamGenerator<T3>::iterator begin3_;
-    const typename ParamGenerator<T3>::iterator end3_;
-    typename ParamGenerator<T3>::iterator current3_;
-    const typename ParamGenerator<T4>::iterator begin4_;
-    const typename ParamGenerator<T4>::iterator end4_;
-    typename ParamGenerator<T4>::iterator current4_;
-    const typename ParamGenerator<T5>::iterator begin5_;
-    const typename ParamGenerator<T5>::iterator end5_;
-    typename ParamGenerator<T5>::iterator current5_;
-    ParamType current_value_;
-  };  // class CartesianProductGenerator5::Iterator
-
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductGenerator5& other);
-
-  const ParamGenerator<T1> g1_;
-  const ParamGenerator<T2> g2_;
-  const ParamGenerator<T3> g3_;
-  const ParamGenerator<T4> g4_;
-  const ParamGenerator<T5> g5_;
-};  // class CartesianProductGenerator5
-
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6>
-class CartesianProductGenerator6
-    : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5,
-        T6> > {
- public:
-  typedef ::testing::tuple<T1, T2, T3, T4, T5, T6> ParamType;
-
-  CartesianProductGenerator6(const ParamGenerator<T1>& g1,
-      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
-      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
-      const ParamGenerator<T6>& g6)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
-  virtual ~CartesianProductGenerator6() {}
-
-  virtual ParamIteratorInterface<ParamType>* Begin() const {
-    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
-        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin());
-  }
-  virtual ParamIteratorInterface<ParamType>* End() const {
-    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
-        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end());
-  }
-
- private:
-  class Iterator : public ParamIteratorInterface<ParamType> {
-   public:
-    Iterator(const ParamGeneratorInterface<ParamType>* base,
-      const ParamGenerator<T1>& g1,
-      const typename ParamGenerator<T1>::iterator& current1,
-      const ParamGenerator<T2>& g2,
-      const typename ParamGenerator<T2>::iterator& current2,
-      const ParamGenerator<T3>& g3,
-      const typename ParamGenerator<T3>::iterator& current3,
-      const ParamGenerator<T4>& g4,
-      const typename ParamGenerator<T4>::iterator& current4,
-      const ParamGenerator<T5>& g5,
-      const typename ParamGenerator<T5>::iterator& current5,
-      const ParamGenerator<T6>& g6,
-      const typename ParamGenerator<T6>::iterator& current6)
-        : base_(base),
-          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
-          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
-          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
-          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
-          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
-          begin6_(g6.begin()), end6_(g6.end()), current6_(current6)    {
-      ComputeCurrentValue();
-    }
-    virtual ~Iterator() {}
-
-    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
-      return base_;
-    }
-    // Advance should not be called on beyond-of-range iterators
-    // so no component iterators must be beyond end of range, either.
-    virtual void Advance() {
-      assert(!AtEnd());
-      ++current6_;
-      if (current6_ == end6_) {
-        current6_ = begin6_;
-        ++current5_;
-      }
-      if (current5_ == end5_) {
-        current5_ = begin5_;
-        ++current4_;
-      }
-      if (current4_ == end4_) {
-        current4_ = begin4_;
-        ++current3_;
-      }
-      if (current3_ == end3_) {
-        current3_ = begin3_;
-        ++current2_;
-      }
-      if (current2_ == end2_) {
-        current2_ = begin2_;
-        ++current1_;
-      }
-      ComputeCurrentValue();
-    }
-    virtual ParamIteratorInterface<ParamType>* Clone() const {
-      return new Iterator(*this);
-    }
-    virtual const ParamType* Current() const { return &current_value_; }
-    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
-      // Having the same base generator guarantees that the other
-      // iterator is of the same type and we can downcast.
-      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
-          << "The program attempted to compare iterators "
-          << "from different generators." << std::endl;
-      const Iterator* typed_other =
-          CheckedDowncastToActualType<const Iterator>(&other);
-      // We must report iterators equal if they both point beyond their
-      // respective ranges. That can happen in a variety of fashions,
-      // so we have to consult AtEnd().
-      return (AtEnd() && typed_other->AtEnd()) ||
-         (
-          current1_ == typed_other->current1_ &&
-          current2_ == typed_other->current2_ &&
-          current3_ == typed_other->current3_ &&
-          current4_ == typed_other->current4_ &&
-          current5_ == typed_other->current5_ &&
-          current6_ == typed_other->current6_);
-    }
-
-   private:
-    Iterator(const Iterator& other)
-        : base_(other.base_),
-        begin1_(other.begin1_),
-        end1_(other.end1_),
-        current1_(other.current1_),
-        begin2_(other.begin2_),
-        end2_(other.end2_),
-        current2_(other.current2_),
-        begin3_(other.begin3_),
-        end3_(other.end3_),
-        current3_(other.current3_),
-        begin4_(other.begin4_),
-        end4_(other.end4_),
-        current4_(other.current4_),
-        begin5_(other.begin5_),
-        end5_(other.end5_),
-        current5_(other.current5_),
-        begin6_(other.begin6_),
-        end6_(other.end6_),
-        current6_(other.current6_) {
-      ComputeCurrentValue();
-    }
-
-    void ComputeCurrentValue() {
-      if (!AtEnd())
-        current_value_ = ParamType(*current1_, *current2_, *current3_,
-            *current4_, *current5_, *current6_);
-    }
-    bool AtEnd() const {
-      // We must report iterator past the end of the range when either of the
-      // component iterators has reached the end of its range.
-      return
-          current1_ == end1_ ||
-          current2_ == end2_ ||
-          current3_ == end3_ ||
-          current4_ == end4_ ||
-          current5_ == end5_ ||
-          current6_ == end6_;
-    }
-
-    // No implementation - assignment is unsupported.
-    void operator=(const Iterator& other);
-
-    const ParamGeneratorInterface<ParamType>* const base_;
-    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
-    // current[i]_ is the actual traversing iterator.
-    const typename ParamGenerator<T1>::iterator begin1_;
-    const typename ParamGenerator<T1>::iterator end1_;
-    typename ParamGenerator<T1>::iterator current1_;
-    const typename ParamGenerator<T2>::iterator begin2_;
-    const typename ParamGenerator<T2>::iterator end2_;
-    typename ParamGenerator<T2>::iterator current2_;
-    const typename ParamGenerator<T3>::iterator begin3_;
-    const typename ParamGenerator<T3>::iterator end3_;
-    typename ParamGenerator<T3>::iterator current3_;
-    const typename ParamGenerator<T4>::iterator begin4_;
-    const typename ParamGenerator<T4>::iterator end4_;
-    typename ParamGenerator<T4>::iterator current4_;
-    const typename ParamGenerator<T5>::iterator begin5_;
-    const typename ParamGenerator<T5>::iterator end5_;
-    typename ParamGenerator<T5>::iterator current5_;
-    const typename ParamGenerator<T6>::iterator begin6_;
-    const typename ParamGenerator<T6>::iterator end6_;
-    typename ParamGenerator<T6>::iterator current6_;
-    ParamType current_value_;
-  };  // class CartesianProductGenerator6::Iterator
-
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductGenerator6& other);
-
-  const ParamGenerator<T1> g1_;
-  const ParamGenerator<T2> g2_;
-  const ParamGenerator<T3> g3_;
-  const ParamGenerator<T4> g4_;
-  const ParamGenerator<T5> g5_;
-  const ParamGenerator<T6> g6_;
-};  // class CartesianProductGenerator6
-
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7>
-class CartesianProductGenerator7
-    : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6,
-        T7> > {
- public:
-  typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType;
-
-  CartesianProductGenerator7(const ParamGenerator<T1>& g1,
-      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
-      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
-      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
-  virtual ~CartesianProductGenerator7() {}
-
-  virtual ParamIteratorInterface<ParamType>* Begin() const {
-    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
-        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
-        g7_.begin());
-  }
-  virtual ParamIteratorInterface<ParamType>* End() const {
-    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
-        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end());
-  }
-
- private:
-  class Iterator : public ParamIteratorInterface<ParamType> {
-   public:
-    Iterator(const ParamGeneratorInterface<ParamType>* base,
-      const ParamGenerator<T1>& g1,
-      const typename ParamGenerator<T1>::iterator& current1,
-      const ParamGenerator<T2>& g2,
-      const typename ParamGenerator<T2>::iterator& current2,
-      const ParamGenerator<T3>& g3,
-      const typename ParamGenerator<T3>::iterator& current3,
-      const ParamGenerator<T4>& g4,
-      const typename ParamGenerator<T4>::iterator& current4,
-      const ParamGenerator<T5>& g5,
-      const typename ParamGenerator<T5>::iterator& current5,
-      const ParamGenerator<T6>& g6,
-      const typename ParamGenerator<T6>::iterator& current6,
-      const ParamGenerator<T7>& g7,
-      const typename ParamGenerator<T7>::iterator& current7)
-        : base_(base),
-          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
-          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
-          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
-          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
-          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
-          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
-          begin7_(g7.begin()), end7_(g7.end()), current7_(current7)    {
-      ComputeCurrentValue();
-    }
-    virtual ~Iterator() {}
-
-    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
-      return base_;
-    }
-    // Advance should not be called on beyond-of-range iterators
-    // so no component iterators must be beyond end of range, either.
-    virtual void Advance() {
-      assert(!AtEnd());
-      ++current7_;
-      if (current7_ == end7_) {
-        current7_ = begin7_;
-        ++current6_;
-      }
-      if (current6_ == end6_) {
-        current6_ = begin6_;
-        ++current5_;
-      }
-      if (current5_ == end5_) {
-        current5_ = begin5_;
-        ++current4_;
-      }
-      if (current4_ == end4_) {
-        current4_ = begin4_;
-        ++current3_;
-      }
-      if (current3_ == end3_) {
-        current3_ = begin3_;
-        ++current2_;
-      }
-      if (current2_ == end2_) {
-        current2_ = begin2_;
-        ++current1_;
-      }
-      ComputeCurrentValue();
-    }
-    virtual ParamIteratorInterface<ParamType>* Clone() const {
-      return new Iterator(*this);
-    }
-    virtual const ParamType* Current() const { return &current_value_; }
-    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
-      // Having the same base generator guarantees that the other
-      // iterator is of the same type and we can downcast.
-      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
-          << "The program attempted to compare iterators "
-          << "from different generators." << std::endl;
-      const Iterator* typed_other =
-          CheckedDowncastToActualType<const Iterator>(&other);
-      // We must report iterators equal if they both point beyond their
-      // respective ranges. That can happen in a variety of fashions,
-      // so we have to consult AtEnd().
-      return (AtEnd() && typed_other->AtEnd()) ||
-         (
-          current1_ == typed_other->current1_ &&
-          current2_ == typed_other->current2_ &&
-          current3_ == typed_other->current3_ &&
-          current4_ == typed_other->current4_ &&
-          current5_ == typed_other->current5_ &&
-          current6_ == typed_other->current6_ &&
-          current7_ == typed_other->current7_);
-    }
-
-   private:
-    Iterator(const Iterator& other)
-        : base_(other.base_),
-        begin1_(other.begin1_),
-        end1_(other.end1_),
-        current1_(other.current1_),
-        begin2_(other.begin2_),
-        end2_(other.end2_),
-        current2_(other.current2_),
-        begin3_(other.begin3_),
-        end3_(other.end3_),
-        current3_(other.current3_),
-        begin4_(other.begin4_),
-        end4_(other.end4_),
-        current4_(other.current4_),
-        begin5_(other.begin5_),
-        end5_(other.end5_),
-        current5_(other.current5_),
-        begin6_(other.begin6_),
-        end6_(other.end6_),
-        current6_(other.current6_),
-        begin7_(other.begin7_),
-        end7_(other.end7_),
-        current7_(other.current7_) {
-      ComputeCurrentValue();
-    }
-
-    void ComputeCurrentValue() {
-      if (!AtEnd())
-        current_value_ = ParamType(*current1_, *current2_, *current3_,
-            *current4_, *current5_, *current6_, *current7_);
-    }
-    bool AtEnd() const {
-      // We must report iterator past the end of the range when either of the
-      // component iterators has reached the end of its range.
-      return
-          current1_ == end1_ ||
-          current2_ == end2_ ||
-          current3_ == end3_ ||
-          current4_ == end4_ ||
-          current5_ == end5_ ||
-          current6_ == end6_ ||
-          current7_ == end7_;
-    }
-
-    // No implementation - assignment is unsupported.
-    void operator=(const Iterator& other);
-
-    const ParamGeneratorInterface<ParamType>* const base_;
-    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
-    // current[i]_ is the actual traversing iterator.
-    const typename ParamGenerator<T1>::iterator begin1_;
-    const typename ParamGenerator<T1>::iterator end1_;
-    typename ParamGenerator<T1>::iterator current1_;
-    const typename ParamGenerator<T2>::iterator begin2_;
-    const typename ParamGenerator<T2>::iterator end2_;
-    typename ParamGenerator<T2>::iterator current2_;
-    const typename ParamGenerator<T3>::iterator begin3_;
-    const typename ParamGenerator<T3>::iterator end3_;
-    typename ParamGenerator<T3>::iterator current3_;
-    const typename ParamGenerator<T4>::iterator begin4_;
-    const typename ParamGenerator<T4>::iterator end4_;
-    typename ParamGenerator<T4>::iterator current4_;
-    const typename ParamGenerator<T5>::iterator begin5_;
-    const typename ParamGenerator<T5>::iterator end5_;
-    typename ParamGenerator<T5>::iterator current5_;
-    const typename ParamGenerator<T6>::iterator begin6_;
-    const typename ParamGenerator<T6>::iterator end6_;
-    typename ParamGenerator<T6>::iterator current6_;
-    const typename ParamGenerator<T7>::iterator begin7_;
-    const typename ParamGenerator<T7>::iterator end7_;
-    typename ParamGenerator<T7>::iterator current7_;
-    ParamType current_value_;
-  };  // class CartesianProductGenerator7::Iterator
-
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductGenerator7& other);
-
-  const ParamGenerator<T1> g1_;
-  const ParamGenerator<T2> g2_;
-  const ParamGenerator<T3> g3_;
-  const ParamGenerator<T4> g4_;
-  const ParamGenerator<T5> g5_;
-  const ParamGenerator<T6> g6_;
-  const ParamGenerator<T7> g7_;
-};  // class CartesianProductGenerator7
-
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8>
-class CartesianProductGenerator8
-    : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6,
-        T7, T8> > {
- public:
-  typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType;
-
-  CartesianProductGenerator8(const ParamGenerator<T1>& g1,
-      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
-      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
-      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
-      const ParamGenerator<T8>& g8)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
-          g8_(g8) {}
-  virtual ~CartesianProductGenerator8() {}
-
-  virtual ParamIteratorInterface<ParamType>* Begin() const {
-    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
-        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
-        g7_.begin(), g8_, g8_.begin());
-  }
-  virtual ParamIteratorInterface<ParamType>* End() const {
-    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
-        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
-        g8_.end());
-  }
-
- private:
-  class Iterator : public ParamIteratorInterface<ParamType> {
-   public:
-    Iterator(const ParamGeneratorInterface<ParamType>* base,
-      const ParamGenerator<T1>& g1,
-      const typename ParamGenerator<T1>::iterator& current1,
-      const ParamGenerator<T2>& g2,
-      const typename ParamGenerator<T2>::iterator& current2,
-      const ParamGenerator<T3>& g3,
-      const typename ParamGenerator<T3>::iterator& current3,
-      const ParamGenerator<T4>& g4,
-      const typename ParamGenerator<T4>::iterator& current4,
-      const ParamGenerator<T5>& g5,
-      const typename ParamGenerator<T5>::iterator& current5,
-      const ParamGenerator<T6>& g6,
-      const typename ParamGenerator<T6>::iterator& current6,
-      const ParamGenerator<T7>& g7,
-      const typename ParamGenerator<T7>::iterator& current7,
-      const ParamGenerator<T8>& g8,
-      const typename ParamGenerator<T8>::iterator& current8)
-        : base_(base),
-          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
-          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
-          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
-          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
-          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
-          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
-          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
-          begin8_(g8.begin()), end8_(g8.end()), current8_(current8)    {
-      ComputeCurrentValue();
-    }
-    virtual ~Iterator() {}
-
-    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
-      return base_;
-    }
-    // Advance should not be called on beyond-of-range iterators
-    // so no component iterators must be beyond end of range, either.
-    virtual void Advance() {
-      assert(!AtEnd());
-      ++current8_;
-      if (current8_ == end8_) {
-        current8_ = begin8_;
-        ++current7_;
-      }
-      if (current7_ == end7_) {
-        current7_ = begin7_;
-        ++current6_;
-      }
-      if (current6_ == end6_) {
-        current6_ = begin6_;
-        ++current5_;
-      }
-      if (current5_ == end5_) {
-        current5_ = begin5_;
-        ++current4_;
-      }
-      if (current4_ == end4_) {
-        current4_ = begin4_;
-        ++current3_;
-      }
-      if (current3_ == end3_) {
-        current3_ = begin3_;
-        ++current2_;
-      }
-      if (current2_ == end2_) {
-        current2_ = begin2_;
-        ++current1_;
-      }
-      ComputeCurrentValue();
-    }
-    virtual ParamIteratorInterface<ParamType>* Clone() const {
-      return new Iterator(*this);
-    }
-    virtual const ParamType* Current() const { return &current_value_; }
-    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
-      // Having the same base generator guarantees that the other
-      // iterator is of the same type and we can downcast.
-      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
-          << "The program attempted to compare iterators "
-          << "from different generators." << std::endl;
-      const Iterator* typed_other =
-          CheckedDowncastToActualType<const Iterator>(&other);
-      // We must report iterators equal if they both point beyond their
-      // respective ranges. That can happen in a variety of fashions,
-      // so we have to consult AtEnd().
-      return (AtEnd() && typed_other->AtEnd()) ||
-         (
-          current1_ == typed_other->current1_ &&
-          current2_ == typed_other->current2_ &&
-          current3_ == typed_other->current3_ &&
-          current4_ == typed_other->current4_ &&
-          current5_ == typed_other->current5_ &&
-          current6_ == typed_other->current6_ &&
-          current7_ == typed_other->current7_ &&
-          current8_ == typed_other->current8_);
-    }
-
-   private:
-    Iterator(const Iterator& other)
-        : base_(other.base_),
-        begin1_(other.begin1_),
-        end1_(other.end1_),
-        current1_(other.current1_),
-        begin2_(other.begin2_),
-        end2_(other.end2_),
-        current2_(other.current2_),
-        begin3_(other.begin3_),
-        end3_(other.end3_),
-        current3_(other.current3_),
-        begin4_(other.begin4_),
-        end4_(other.end4_),
-        current4_(other.current4_),
-        begin5_(other.begin5_),
-        end5_(other.end5_),
-        current5_(other.current5_),
-        begin6_(other.begin6_),
-        end6_(other.end6_),
-        current6_(other.current6_),
-        begin7_(other.begin7_),
-        end7_(other.end7_),
-        current7_(other.current7_),
-        begin8_(other.begin8_),
-        end8_(other.end8_),
-        current8_(other.current8_) {
-      ComputeCurrentValue();
-    }
-
-    void ComputeCurrentValue() {
-      if (!AtEnd())
-        current_value_ = ParamType(*current1_, *current2_, *current3_,
-            *current4_, *current5_, *current6_, *current7_, *current8_);
-    }
-    bool AtEnd() const {
-      // We must report iterator past the end of the range when either of the
-      // component iterators has reached the end of its range.
-      return
-          current1_ == end1_ ||
-          current2_ == end2_ ||
-          current3_ == end3_ ||
-          current4_ == end4_ ||
-          current5_ == end5_ ||
-          current6_ == end6_ ||
-          current7_ == end7_ ||
-          current8_ == end8_;
-    }
-
-    // No implementation - assignment is unsupported.
-    void operator=(const Iterator& other);
-
-    const ParamGeneratorInterface<ParamType>* const base_;
-    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
-    // current[i]_ is the actual traversing iterator.
-    const typename ParamGenerator<T1>::iterator begin1_;
-    const typename ParamGenerator<T1>::iterator end1_;
-    typename ParamGenerator<T1>::iterator current1_;
-    const typename ParamGenerator<T2>::iterator begin2_;
-    const typename ParamGenerator<T2>::iterator end2_;
-    typename ParamGenerator<T2>::iterator current2_;
-    const typename ParamGenerator<T3>::iterator begin3_;
-    const typename ParamGenerator<T3>::iterator end3_;
-    typename ParamGenerator<T3>::iterator current3_;
-    const typename ParamGenerator<T4>::iterator begin4_;
-    const typename ParamGenerator<T4>::iterator end4_;
-    typename ParamGenerator<T4>::iterator current4_;
-    const typename ParamGenerator<T5>::iterator begin5_;
-    const typename ParamGenerator<T5>::iterator end5_;
-    typename ParamGenerator<T5>::iterator current5_;
-    const typename ParamGenerator<T6>::iterator begin6_;
-    const typename ParamGenerator<T6>::iterator end6_;
-    typename ParamGenerator<T6>::iterator current6_;
-    const typename ParamGenerator<T7>::iterator begin7_;
-    const typename ParamGenerator<T7>::iterator end7_;
-    typename ParamGenerator<T7>::iterator current7_;
-    const typename ParamGenerator<T8>::iterator begin8_;
-    const typename ParamGenerator<T8>::iterator end8_;
-    typename ParamGenerator<T8>::iterator current8_;
-    ParamType current_value_;
-  };  // class CartesianProductGenerator8::Iterator
-
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductGenerator8& other);
-
-  const ParamGenerator<T1> g1_;
-  const ParamGenerator<T2> g2_;
-  const ParamGenerator<T3> g3_;
-  const ParamGenerator<T4> g4_;
-  const ParamGenerator<T5> g5_;
-  const ParamGenerator<T6> g6_;
-  const ParamGenerator<T7> g7_;
-  const ParamGenerator<T8> g8_;
-};  // class CartesianProductGenerator8
-
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9>
-class CartesianProductGenerator9
-    : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6,
-        T7, T8, T9> > {
- public:
-  typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType;
-
-  CartesianProductGenerator9(const ParamGenerator<T1>& g1,
-      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
-      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
-      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
-      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
-          g9_(g9) {}
-  virtual ~CartesianProductGenerator9() {}
-
-  virtual ParamIteratorInterface<ParamType>* Begin() const {
-    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
-        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
-        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin());
-  }
-  virtual ParamIteratorInterface<ParamType>* End() const {
-    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
-        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
-        g8_.end(), g9_, g9_.end());
-  }
-
- private:
-  class Iterator : public ParamIteratorInterface<ParamType> {
-   public:
-    Iterator(const ParamGeneratorInterface<ParamType>* base,
-      const ParamGenerator<T1>& g1,
-      const typename ParamGenerator<T1>::iterator& current1,
-      const ParamGenerator<T2>& g2,
-      const typename ParamGenerator<T2>::iterator& current2,
-      const ParamGenerator<T3>& g3,
-      const typename ParamGenerator<T3>::iterator& current3,
-      const ParamGenerator<T4>& g4,
-      const typename ParamGenerator<T4>::iterator& current4,
-      const ParamGenerator<T5>& g5,
-      const typename ParamGenerator<T5>::iterator& current5,
-      const ParamGenerator<T6>& g6,
-      const typename ParamGenerator<T6>::iterator& current6,
-      const ParamGenerator<T7>& g7,
-      const typename ParamGenerator<T7>::iterator& current7,
-      const ParamGenerator<T8>& g8,
-      const typename ParamGenerator<T8>::iterator& current8,
-      const ParamGenerator<T9>& g9,
-      const typename ParamGenerator<T9>::iterator& current9)
-        : base_(base),
-          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
-          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
-          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
-          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
-          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
-          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
-          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
-          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
-          begin9_(g9.begin()), end9_(g9.end()), current9_(current9)    {
-      ComputeCurrentValue();
-    }
-    virtual ~Iterator() {}
-
-    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
-      return base_;
-    }
-    // Advance should not be called on beyond-of-range iterators
-    // so no component iterators must be beyond end of range, either.
-    virtual void Advance() {
-      assert(!AtEnd());
-      ++current9_;
-      if (current9_ == end9_) {
-        current9_ = begin9_;
-        ++current8_;
-      }
-      if (current8_ == end8_) {
-        current8_ = begin8_;
-        ++current7_;
-      }
-      if (current7_ == end7_) {
-        current7_ = begin7_;
-        ++current6_;
-      }
-      if (current6_ == end6_) {
-        current6_ = begin6_;
-        ++current5_;
-      }
-      if (current5_ == end5_) {
-        current5_ = begin5_;
-        ++current4_;
-      }
-      if (current4_ == end4_) {
-        current4_ = begin4_;
-        ++current3_;
-      }
-      if (current3_ == end3_) {
-        current3_ = begin3_;
-        ++current2_;
-      }
-      if (current2_ == end2_) {
-        current2_ = begin2_;
-        ++current1_;
-      }
-      ComputeCurrentValue();
-    }
-    virtual ParamIteratorInterface<ParamType>* Clone() const {
-      return new Iterator(*this);
-    }
-    virtual const ParamType* Current() const { return &current_value_; }
-    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
-      // Having the same base generator guarantees that the other
-      // iterator is of the same type and we can downcast.
-      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
-          << "The program attempted to compare iterators "
-          << "from different generators." << std::endl;
-      const Iterator* typed_other =
-          CheckedDowncastToActualType<const Iterator>(&other);
-      // We must report iterators equal if they both point beyond their
-      // respective ranges. That can happen in a variety of fashions,
-      // so we have to consult AtEnd().
-      return (AtEnd() && typed_other->AtEnd()) ||
-         (
-          current1_ == typed_other->current1_ &&
-          current2_ == typed_other->current2_ &&
-          current3_ == typed_other->current3_ &&
-          current4_ == typed_other->current4_ &&
-          current5_ == typed_other->current5_ &&
-          current6_ == typed_other->current6_ &&
-          current7_ == typed_other->current7_ &&
-          current8_ == typed_other->current8_ &&
-          current9_ == typed_other->current9_);
-    }
-
-   private:
-    Iterator(const Iterator& other)
-        : base_(other.base_),
-        begin1_(other.begin1_),
-        end1_(other.end1_),
-        current1_(other.current1_),
-        begin2_(other.begin2_),
-        end2_(other.end2_),
-        current2_(other.current2_),
-        begin3_(other.begin3_),
-        end3_(other.end3_),
-        current3_(other.current3_),
-        begin4_(other.begin4_),
-        end4_(other.end4_),
-        current4_(other.current4_),
-        begin5_(other.begin5_),
-        end5_(other.end5_),
-        current5_(other.current5_),
-        begin6_(other.begin6_),
-        end6_(other.end6_),
-        current6_(other.current6_),
-        begin7_(other.begin7_),
-        end7_(other.end7_),
-        current7_(other.current7_),
-        begin8_(other.begin8_),
-        end8_(other.end8_),
-        current8_(other.current8_),
-        begin9_(other.begin9_),
-        end9_(other.end9_),
-        current9_(other.current9_) {
-      ComputeCurrentValue();
-    }
-
-    void ComputeCurrentValue() {
-      if (!AtEnd())
-        current_value_ = ParamType(*current1_, *current2_, *current3_,
-            *current4_, *current5_, *current6_, *current7_, *current8_,
-            *current9_);
-    }
-    bool AtEnd() const {
-      // We must report iterator past the end of the range when either of the
-      // component iterators has reached the end of its range.
-      return
-          current1_ == end1_ ||
-          current2_ == end2_ ||
-          current3_ == end3_ ||
-          current4_ == end4_ ||
-          current5_ == end5_ ||
-          current6_ == end6_ ||
-          current7_ == end7_ ||
-          current8_ == end8_ ||
-          current9_ == end9_;
-    }
-
-    // No implementation - assignment is unsupported.
-    void operator=(const Iterator& other);
-
-    const ParamGeneratorInterface<ParamType>* const base_;
-    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
-    // current[i]_ is the actual traversing iterator.
-    const typename ParamGenerator<T1>::iterator begin1_;
-    const typename ParamGenerator<T1>::iterator end1_;
-    typename ParamGenerator<T1>::iterator current1_;
-    const typename ParamGenerator<T2>::iterator begin2_;
-    const typename ParamGenerator<T2>::iterator end2_;
-    typename ParamGenerator<T2>::iterator current2_;
-    const typename ParamGenerator<T3>::iterator begin3_;
-    const typename ParamGenerator<T3>::iterator end3_;
-    typename ParamGenerator<T3>::iterator current3_;
-    const typename ParamGenerator<T4>::iterator begin4_;
-    const typename ParamGenerator<T4>::iterator end4_;
-    typename ParamGenerator<T4>::iterator current4_;
-    const typename ParamGenerator<T5>::iterator begin5_;
-    const typename ParamGenerator<T5>::iterator end5_;
-    typename ParamGenerator<T5>::iterator current5_;
-    const typename ParamGenerator<T6>::iterator begin6_;
-    const typename ParamGenerator<T6>::iterator end6_;
-    typename ParamGenerator<T6>::iterator current6_;
-    const typename ParamGenerator<T7>::iterator begin7_;
-    const typename ParamGenerator<T7>::iterator end7_;
-    typename ParamGenerator<T7>::iterator current7_;
-    const typename ParamGenerator<T8>::iterator begin8_;
-    const typename ParamGenerator<T8>::iterator end8_;
-    typename ParamGenerator<T8>::iterator current8_;
-    const typename ParamGenerator<T9>::iterator begin9_;
-    const typename ParamGenerator<T9>::iterator end9_;
-    typename ParamGenerator<T9>::iterator current9_;
-    ParamType current_value_;
-  };  // class CartesianProductGenerator9::Iterator
-
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductGenerator9& other);
-
-  const ParamGenerator<T1> g1_;
-  const ParamGenerator<T2> g2_;
-  const ParamGenerator<T3> g3_;
-  const ParamGenerator<T4> g4_;
-  const ParamGenerator<T5> g5_;
-  const ParamGenerator<T6> g6_;
-  const ParamGenerator<T7> g7_;
-  const ParamGenerator<T8> g8_;
-  const ParamGenerator<T9> g9_;
-};  // class CartesianProductGenerator9
-
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10>
-class CartesianProductGenerator10
-    : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6,
-        T7, T8, T9, T10> > {
- public:
-  typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType;
-
-  CartesianProductGenerator10(const ParamGenerator<T1>& g1,
-      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
-      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
-      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
-      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9,
-      const ParamGenerator<T10>& g10)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
-          g9_(g9), g10_(g10) {}
-  virtual ~CartesianProductGenerator10() {}
-
-  virtual ParamIteratorInterface<ParamType>* Begin() const {
-    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
-        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
-        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin());
-  }
-  virtual ParamIteratorInterface<ParamType>* End() const {
-    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
-        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
-        g8_.end(), g9_, g9_.end(), g10_, g10_.end());
-  }
-
- private:
-  class Iterator : public ParamIteratorInterface<ParamType> {
-   public:
-    Iterator(const ParamGeneratorInterface<ParamType>* base,
-      const ParamGenerator<T1>& g1,
-      const typename ParamGenerator<T1>::iterator& current1,
-      const ParamGenerator<T2>& g2,
-      const typename ParamGenerator<T2>::iterator& current2,
-      const ParamGenerator<T3>& g3,
-      const typename ParamGenerator<T3>::iterator& current3,
-      const ParamGenerator<T4>& g4,
-      const typename ParamGenerator<T4>::iterator& current4,
-      const ParamGenerator<T5>& g5,
-      const typename ParamGenerator<T5>::iterator& current5,
-      const ParamGenerator<T6>& g6,
-      const typename ParamGenerator<T6>::iterator& current6,
-      const ParamGenerator<T7>& g7,
-      const typename ParamGenerator<T7>::iterator& current7,
-      const ParamGenerator<T8>& g8,
-      const typename ParamGenerator<T8>::iterator& current8,
-      const ParamGenerator<T9>& g9,
-      const typename ParamGenerator<T9>::iterator& current9,
-      const ParamGenerator<T10>& g10,
-      const typename ParamGenerator<T10>::iterator& current10)
-        : base_(base),
-          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
-          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
-          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
-          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
-          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
-          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
-          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
-          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
-          begin9_(g9.begin()), end9_(g9.end()), current9_(current9),
-          begin10_(g10.begin()), end10_(g10.end()), current10_(current10)    {
-      ComputeCurrentValue();
-    }
-    virtual ~Iterator() {}
-
-    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
-      return base_;
-    }
-    // Advance should not be called on beyond-of-range iterators
-    // so no component iterators must be beyond end of range, either.
-    virtual void Advance() {
-      assert(!AtEnd());
-      ++current10_;
-      if (current10_ == end10_) {
-        current10_ = begin10_;
-        ++current9_;
-      }
-      if (current9_ == end9_) {
-        current9_ = begin9_;
-        ++current8_;
-      }
-      if (current8_ == end8_) {
-        current8_ = begin8_;
-        ++current7_;
-      }
-      if (current7_ == end7_) {
-        current7_ = begin7_;
-        ++current6_;
-      }
-      if (current6_ == end6_) {
-        current6_ = begin6_;
-        ++current5_;
-      }
-      if (current5_ == end5_) {
-        current5_ = begin5_;
-        ++current4_;
-      }
-      if (current4_ == end4_) {
-        current4_ = begin4_;
-        ++current3_;
-      }
-      if (current3_ == end3_) {
-        current3_ = begin3_;
-        ++current2_;
-      }
-      if (current2_ == end2_) {
-        current2_ = begin2_;
-        ++current1_;
-      }
-      ComputeCurrentValue();
-    }
-    virtual ParamIteratorInterface<ParamType>* Clone() const {
-      return new Iterator(*this);
-    }
-    virtual const ParamType* Current() const { return &current_value_; }
-    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
-      // Having the same base generator guarantees that the other
-      // iterator is of the same type and we can downcast.
-      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
-          << "The program attempted to compare iterators "
-          << "from different generators." << std::endl;
-      const Iterator* typed_other =
-          CheckedDowncastToActualType<const Iterator>(&other);
-      // We must report iterators equal if they both point beyond their
-      // respective ranges. That can happen in a variety of fashions,
-      // so we have to consult AtEnd().
-      return (AtEnd() && typed_other->AtEnd()) ||
-         (
-          current1_ == typed_other->current1_ &&
-          current2_ == typed_other->current2_ &&
-          current3_ == typed_other->current3_ &&
-          current4_ == typed_other->current4_ &&
-          current5_ == typed_other->current5_ &&
-          current6_ == typed_other->current6_ &&
-          current7_ == typed_other->current7_ &&
-          current8_ == typed_other->current8_ &&
-          current9_ == typed_other->current9_ &&
-          current10_ == typed_other->current10_);
-    }
-
-   private:
-    Iterator(const Iterator& other)
-        : base_(other.base_),
-        begin1_(other.begin1_),
-        end1_(other.end1_),
-        current1_(other.current1_),
-        begin2_(other.begin2_),
-        end2_(other.end2_),
-        current2_(other.current2_),
-        begin3_(other.begin3_),
-        end3_(other.end3_),
-        current3_(other.current3_),
-        begin4_(other.begin4_),
-        end4_(other.end4_),
-        current4_(other.current4_),
-        begin5_(other.begin5_),
-        end5_(other.end5_),
-        current5_(other.current5_),
-        begin6_(other.begin6_),
-        end6_(other.end6_),
-        current6_(other.current6_),
-        begin7_(other.begin7_),
-        end7_(other.end7_),
-        current7_(other.current7_),
-        begin8_(other.begin8_),
-        end8_(other.end8_),
-        current8_(other.current8_),
-        begin9_(other.begin9_),
-        end9_(other.end9_),
-        current9_(other.current9_),
-        begin10_(other.begin10_),
-        end10_(other.end10_),
-        current10_(other.current10_) {
-      ComputeCurrentValue();
-    }
-
-    void ComputeCurrentValue() {
-      if (!AtEnd())
-        current_value_ = ParamType(*current1_, *current2_, *current3_,
-            *current4_, *current5_, *current6_, *current7_, *current8_,
-            *current9_, *current10_);
-    }
-    bool AtEnd() const {
-      // We must report iterator past the end of the range when either of the
-      // component iterators has reached the end of its range.
-      return
-          current1_ == end1_ ||
-          current2_ == end2_ ||
-          current3_ == end3_ ||
-          current4_ == end4_ ||
-          current5_ == end5_ ||
-          current6_ == end6_ ||
-          current7_ == end7_ ||
-          current8_ == end8_ ||
-          current9_ == end9_ ||
-          current10_ == end10_;
-    }
-
-    // No implementation - assignment is unsupported.
-    void operator=(const Iterator& other);
-
-    const ParamGeneratorInterface<ParamType>* const base_;
-    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
-    // current[i]_ is the actual traversing iterator.
-    const typename ParamGenerator<T1>::iterator begin1_;
-    const typename ParamGenerator<T1>::iterator end1_;
-    typename ParamGenerator<T1>::iterator current1_;
-    const typename ParamGenerator<T2>::iterator begin2_;
-    const typename ParamGenerator<T2>::iterator end2_;
-    typename ParamGenerator<T2>::iterator current2_;
-    const typename ParamGenerator<T3>::iterator begin3_;
-    const typename ParamGenerator<T3>::iterator end3_;
-    typename ParamGenerator<T3>::iterator current3_;
-    const typename ParamGenerator<T4>::iterator begin4_;
-    const typename ParamGenerator<T4>::iterator end4_;
-    typename ParamGenerator<T4>::iterator current4_;
-    const typename ParamGenerator<T5>::iterator begin5_;
-    const typename ParamGenerator<T5>::iterator end5_;
-    typename ParamGenerator<T5>::iterator current5_;
-    const typename ParamGenerator<T6>::iterator begin6_;
-    const typename ParamGenerator<T6>::iterator end6_;
-    typename ParamGenerator<T6>::iterator current6_;
-    const typename ParamGenerator<T7>::iterator begin7_;
-    const typename ParamGenerator<T7>::iterator end7_;
-    typename ParamGenerator<T7>::iterator current7_;
-    const typename ParamGenerator<T8>::iterator begin8_;
-    const typename ParamGenerator<T8>::iterator end8_;
-    typename ParamGenerator<T8>::iterator current8_;
-    const typename ParamGenerator<T9>::iterator begin9_;
-    const typename ParamGenerator<T9>::iterator end9_;
-    typename ParamGenerator<T9>::iterator current9_;
-    const typename ParamGenerator<T10>::iterator begin10_;
-    const typename ParamGenerator<T10>::iterator end10_;
-    typename ParamGenerator<T10>::iterator current10_;
-    ParamType current_value_;
-  };  // class CartesianProductGenerator10::Iterator
-
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductGenerator10& other);
-
-  const ParamGenerator<T1> g1_;
-  const ParamGenerator<T2> g2_;
-  const ParamGenerator<T3> g3_;
-  const ParamGenerator<T4> g4_;
-  const ParamGenerator<T5> g5_;
-  const ParamGenerator<T6> g6_;
-  const ParamGenerator<T7> g7_;
-  const ParamGenerator<T8> g8_;
-  const ParamGenerator<T9> g9_;
-  const ParamGenerator<T10> g10_;
-};  // class CartesianProductGenerator10
-
-
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
-//
-// Helper classes providing Combine() with polymorphic features. They allow
-// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
-// convertible to U.
-//
-template <class Generator1, class Generator2>
-class CartesianProductHolder2 {
- public:
-CartesianProductHolder2(const Generator1& g1, const Generator2& g2)
-      : g1_(g1), g2_(g2) {}
-  template <typename T1, typename T2>
-  operator ParamGenerator< ::testing::tuple<T1, T2> >() const {
-    return ParamGenerator< ::testing::tuple<T1, T2> >(
-        new CartesianProductGenerator2<T1, T2>(
-        static_cast<ParamGenerator<T1> >(g1_),
-        static_cast<ParamGenerator<T2> >(g2_)));
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductHolder2& other);
-
-  const Generator1 g1_;
-  const Generator2 g2_;
-};  // class CartesianProductHolder2
-
-template <class Generator1, class Generator2, class Generator3>
-class CartesianProductHolder3 {
- public:
-CartesianProductHolder3(const Generator1& g1, const Generator2& g2,
-    const Generator3& g3)
-      : g1_(g1), g2_(g2), g3_(g3) {}
-  template <typename T1, typename T2, typename T3>
-  operator ParamGenerator< ::testing::tuple<T1, T2, T3> >() const {
-    return ParamGenerator< ::testing::tuple<T1, T2, T3> >(
-        new CartesianProductGenerator3<T1, T2, T3>(
-        static_cast<ParamGenerator<T1> >(g1_),
-        static_cast<ParamGenerator<T2> >(g2_),
-        static_cast<ParamGenerator<T3> >(g3_)));
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductHolder3& other);
-
-  const Generator1 g1_;
-  const Generator2 g2_;
-  const Generator3 g3_;
-};  // class CartesianProductHolder3
-
-template <class Generator1, class Generator2, class Generator3,
-    class Generator4>
-class CartesianProductHolder4 {
- public:
-CartesianProductHolder4(const Generator1& g1, const Generator2& g2,
-    const Generator3& g3, const Generator4& g4)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
-  template <typename T1, typename T2, typename T3, typename T4>
-  operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4> >() const {
-    return ParamGenerator< ::testing::tuple<T1, T2, T3, T4> >(
-        new CartesianProductGenerator4<T1, T2, T3, T4>(
-        static_cast<ParamGenerator<T1> >(g1_),
-        static_cast<ParamGenerator<T2> >(g2_),
-        static_cast<ParamGenerator<T3> >(g3_),
-        static_cast<ParamGenerator<T4> >(g4_)));
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductHolder4& other);
-
-  const Generator1 g1_;
-  const Generator2 g2_;
-  const Generator3 g3_;
-  const Generator4 g4_;
-};  // class CartesianProductHolder4
-
-template <class Generator1, class Generator2, class Generator3,
-    class Generator4, class Generator5>
-class CartesianProductHolder5 {
- public:
-CartesianProductHolder5(const Generator1& g1, const Generator2& g2,
-    const Generator3& g3, const Generator4& g4, const Generator5& g5)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
-  template <typename T1, typename T2, typename T3, typename T4, typename T5>
-  operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5> >() const {
-    return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5> >(
-        new CartesianProductGenerator5<T1, T2, T3, T4, T5>(
-        static_cast<ParamGenerator<T1> >(g1_),
-        static_cast<ParamGenerator<T2> >(g2_),
-        static_cast<ParamGenerator<T3> >(g3_),
-        static_cast<ParamGenerator<T4> >(g4_),
-        static_cast<ParamGenerator<T5> >(g5_)));
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductHolder5& other);
-
-  const Generator1 g1_;
-  const Generator2 g2_;
-  const Generator3 g3_;
-  const Generator4 g4_;
-  const Generator5 g5_;
-};  // class CartesianProductHolder5
-
-template <class Generator1, class Generator2, class Generator3,
-    class Generator4, class Generator5, class Generator6>
-class CartesianProductHolder6 {
- public:
-CartesianProductHolder6(const Generator1& g1, const Generator2& g2,
-    const Generator3& g3, const Generator4& g4, const Generator5& g5,
-    const Generator6& g6)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
-  template <typename T1, typename T2, typename T3, typename T4, typename T5,
-      typename T6>
-  operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6> >() const {
-    return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6> >(
-        new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>(
-        static_cast<ParamGenerator<T1> >(g1_),
-        static_cast<ParamGenerator<T2> >(g2_),
-        static_cast<ParamGenerator<T3> >(g3_),
-        static_cast<ParamGenerator<T4> >(g4_),
-        static_cast<ParamGenerator<T5> >(g5_),
-        static_cast<ParamGenerator<T6> >(g6_)));
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductHolder6& other);
-
-  const Generator1 g1_;
-  const Generator2 g2_;
-  const Generator3 g3_;
-  const Generator4 g4_;
-  const Generator5 g5_;
-  const Generator6 g6_;
-};  // class CartesianProductHolder6
-
-template <class Generator1, class Generator2, class Generator3,
-    class Generator4, class Generator5, class Generator6, class Generator7>
-class CartesianProductHolder7 {
- public:
-CartesianProductHolder7(const Generator1& g1, const Generator2& g2,
-    const Generator3& g3, const Generator4& g4, const Generator5& g5,
-    const Generator6& g6, const Generator7& g7)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
-  template <typename T1, typename T2, typename T3, typename T4, typename T5,
-      typename T6, typename T7>
-  operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6,
-      T7> >() const {
-    return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7> >(
-        new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>(
-        static_cast<ParamGenerator<T1> >(g1_),
-        static_cast<ParamGenerator<T2> >(g2_),
-        static_cast<ParamGenerator<T3> >(g3_),
-        static_cast<ParamGenerator<T4> >(g4_),
-        static_cast<ParamGenerator<T5> >(g5_),
-        static_cast<ParamGenerator<T6> >(g6_),
-        static_cast<ParamGenerator<T7> >(g7_)));
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductHolder7& other);
-
-  const Generator1 g1_;
-  const Generator2 g2_;
-  const Generator3 g3_;
-  const Generator4 g4_;
-  const Generator5 g5_;
-  const Generator6 g6_;
-  const Generator7 g7_;
-};  // class CartesianProductHolder7
-
-template <class Generator1, class Generator2, class Generator3,
-    class Generator4, class Generator5, class Generator6, class Generator7,
-    class Generator8>
-class CartesianProductHolder8 {
- public:
-CartesianProductHolder8(const Generator1& g1, const Generator2& g2,
-    const Generator3& g3, const Generator4& g4, const Generator5& g5,
-    const Generator6& g6, const Generator7& g7, const Generator8& g8)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
-          g8_(g8) {}
-  template <typename T1, typename T2, typename T3, typename T4, typename T5,
-      typename T6, typename T7, typename T8>
-  operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7,
-      T8> >() const {
-    return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >(
-        new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>(
-        static_cast<ParamGenerator<T1> >(g1_),
-        static_cast<ParamGenerator<T2> >(g2_),
-        static_cast<ParamGenerator<T3> >(g3_),
-        static_cast<ParamGenerator<T4> >(g4_),
-        static_cast<ParamGenerator<T5> >(g5_),
-        static_cast<ParamGenerator<T6> >(g6_),
-        static_cast<ParamGenerator<T7> >(g7_),
-        static_cast<ParamGenerator<T8> >(g8_)));
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductHolder8& other);
-
-  const Generator1 g1_;
-  const Generator2 g2_;
-  const Generator3 g3_;
-  const Generator4 g4_;
-  const Generator5 g5_;
-  const Generator6 g6_;
-  const Generator7 g7_;
-  const Generator8 g8_;
-};  // class CartesianProductHolder8
-
-template <class Generator1, class Generator2, class Generator3,
-    class Generator4, class Generator5, class Generator6, class Generator7,
-    class Generator8, class Generator9>
-class CartesianProductHolder9 {
- public:
-CartesianProductHolder9(const Generator1& g1, const Generator2& g2,
-    const Generator3& g3, const Generator4& g4, const Generator5& g5,
-    const Generator6& g6, const Generator7& g7, const Generator8& g8,
-    const Generator9& g9)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
-          g9_(g9) {}
-  template <typename T1, typename T2, typename T3, typename T4, typename T5,
-      typename T6, typename T7, typename T8, typename T9>
-  operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
-      T9> >() const {
-    return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
-        T9> >(
-        new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
-        static_cast<ParamGenerator<T1> >(g1_),
-        static_cast<ParamGenerator<T2> >(g2_),
-        static_cast<ParamGenerator<T3> >(g3_),
-        static_cast<ParamGenerator<T4> >(g4_),
-        static_cast<ParamGenerator<T5> >(g5_),
-        static_cast<ParamGenerator<T6> >(g6_),
-        static_cast<ParamGenerator<T7> >(g7_),
-        static_cast<ParamGenerator<T8> >(g8_),
-        static_cast<ParamGenerator<T9> >(g9_)));
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductHolder9& other);
-
-  const Generator1 g1_;
-  const Generator2 g2_;
-  const Generator3 g3_;
-  const Generator4 g4_;
-  const Generator5 g5_;
-  const Generator6 g6_;
-  const Generator7 g7_;
-  const Generator8 g8_;
-  const Generator9 g9_;
-};  // class CartesianProductHolder9
-
-template <class Generator1, class Generator2, class Generator3,
-    class Generator4, class Generator5, class Generator6, class Generator7,
-    class Generator8, class Generator9, class Generator10>
-class CartesianProductHolder10 {
- public:
-CartesianProductHolder10(const Generator1& g1, const Generator2& g2,
-    const Generator3& g3, const Generator4& g4, const Generator5& g5,
-    const Generator6& g6, const Generator7& g7, const Generator8& g8,
-    const Generator9& g9, const Generator10& g10)
-      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
-          g9_(g9), g10_(g10) {}
-  template <typename T1, typename T2, typename T3, typename T4, typename T5,
-      typename T6, typename T7, typename T8, typename T9, typename T10>
-  operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9,
-      T10> >() const {
-    return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9,
-        T10> >(
-        new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
-            T10>(
-        static_cast<ParamGenerator<T1> >(g1_),
-        static_cast<ParamGenerator<T2> >(g2_),
-        static_cast<ParamGenerator<T3> >(g3_),
-        static_cast<ParamGenerator<T4> >(g4_),
-        static_cast<ParamGenerator<T5> >(g5_),
-        static_cast<ParamGenerator<T6> >(g6_),
-        static_cast<ParamGenerator<T7> >(g7_),
-        static_cast<ParamGenerator<T8> >(g8_),
-        static_cast<ParamGenerator<T9> >(g9_),
-        static_cast<ParamGenerator<T10> >(g10_)));
-  }
-
- private:
-  // No implementation - assignment is unsupported.
-  void operator=(const CartesianProductHolder10& other);
-
-  const Generator1 g1_;
-  const Generator2 g2_;
-  const Generator3 g3_;
-  const Generator4 g4_;
-  const Generator5 g5_;
-  const Generator6 g6_;
-  const Generator7 g7_;
-  const Generator8 g8_;
-  const Generator9 g9_;
-  const Generator10 g10_;
-};  // class CartesianProductHolder10
-
-# endif  // GTEST_HAS_COMBINE
+  std::tuple<Gen...> generators_;
+};
 
 }  // namespace internal
 }  // namespace testing
 
-#endif  //  GTEST_HAS_PARAM_TEST
-
-#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
-
-#if GTEST_HAS_PARAM_TEST
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
 
 namespace testing {
 
 // Functions producing parameter generators.
 //
 // Google Test uses these generators to produce parameters for value-
-// parameterized tests. When a parameterized test case is instantiated
+// parameterized tests. When a parameterized test suite is instantiated
 // with a particular generator, Google Test creates and runs tests
 // for each element in the sequence produced by the generator.
 //
-// In the following sample, tests from test case FooTest are instantiated
+// In the following sample, tests from test suite FooTest are instantiated
 // each three times with parameter values 3, 5, and 8:
 //
 // class FooTest : public TestWithParam<int> { ... };
@@ -16947,7 +11447,7 @@
 // }
 // TEST_P(FooTest, TestThat) {
 // }
-// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
+// INSTANTIATE_TEST_SUITE_P(TestSequence, FooTest, Values(3, 5, 8));
 //
 
 // Range() returns generators providing sequences of values in a range.
@@ -17004,13 +11504,13 @@
 //
 // Examples:
 //
-// This instantiates tests from test case StringTest
+// This instantiates tests from test suite StringTest
 // each with C-string values of "foo", "bar", and "baz":
 //
 // const char* strings[] = {"foo", "bar", "baz"};
-// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
+// INSTANTIATE_TEST_SUITE_P(StringSequence, StringTest, ValuesIn(strings));
 //
-// This instantiates tests from test case StlStringTest
+// This instantiates tests from test suite StlStringTest
 // each with STL strings with values "a" and "b":
 //
 // ::std::vector< ::std::string> GetParameterStrings() {
@@ -17020,9 +11520,9 @@
 //   return v;
 // }
 //
-// INSTANTIATE_TEST_CASE_P(CharSequence,
-//                         StlStringTest,
-//                         ValuesIn(GetParameterStrings()));
+// INSTANTIATE_TEST_SUITE_P(CharSequence,
+//                          StlStringTest,
+//                          ValuesIn(GetParameterStrings()));
 //
 //
 // This will also instantiate tests from CharTest
@@ -17035,9 +11535,9 @@
 //   return list;
 // }
 // ::std::list<char> l = GetParameterChars();
-// INSTANTIATE_TEST_CASE_P(CharSequence2,
-//                         CharTest,
-//                         ValuesIn(l.begin(), l.end()));
+// INSTANTIATE_TEST_SUITE_P(CharSequence2,
+//                          CharTest,
+//                          ValuesIn(l.begin(), l.end()));
 //
 template <typename ForwardIterator>
 internal::ParamGenerator<
@@ -17067,869 +11567,22 @@
 // Values(T v1, T v2, ..., T vN)
 //   - returns a generator producing sequences with elements v1, v2, ..., vN.
 //
-// For example, this instantiates tests from test case BarTest each
+// For example, this instantiates tests from test suite BarTest each
 // with values "one", "two", and "three":
 //
-// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
+// INSTANTIATE_TEST_SUITE_P(NumSequence,
+//                          BarTest,
+//                          Values("one", "two", "three"));
 //
-// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
+// This instantiates tests from test suite BazTest each with values 1, 2, 3.5.
 // The exact type of values will depend on the type of parameter in BazTest.
 //
-// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
+// INSTANTIATE_TEST_SUITE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
 //
-// Currently, Values() supports from 1 to 50 parameters.
 //
-template <typename T1>
-internal::ValueArray1<T1> Values(T1 v1) {
-  return internal::ValueArray1<T1>(v1);
-}
-
-template <typename T1, typename T2>
-internal::ValueArray2<T1, T2> Values(T1 v1, T2 v2) {
-  return internal::ValueArray2<T1, T2>(v1, v2);
-}
-
-template <typename T1, typename T2, typename T3>
-internal::ValueArray3<T1, T2, T3> Values(T1 v1, T2 v2, T3 v3) {
-  return internal::ValueArray3<T1, T2, T3>(v1, v2, v3);
-}
-
-template <typename T1, typename T2, typename T3, typename T4>
-internal::ValueArray4<T1, T2, T3, T4> Values(T1 v1, T2 v2, T3 v3, T4 v4) {
-  return internal::ValueArray4<T1, T2, T3, T4>(v1, v2, v3, v4);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-internal::ValueArray5<T1, T2, T3, T4, T5> Values(T1 v1, T2 v2, T3 v3, T4 v4,
-    T5 v5) {
-  return internal::ValueArray5<T1, T2, T3, T4, T5>(v1, v2, v3, v4, v5);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6>
-internal::ValueArray6<T1, T2, T3, T4, T5, T6> Values(T1 v1, T2 v2, T3 v3,
-    T4 v4, T5 v5, T6 v6) {
-  return internal::ValueArray6<T1, T2, T3, T4, T5, T6>(v1, v2, v3, v4, v5, v6);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7>
-internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7> Values(T1 v1, T2 v2, T3 v3,
-    T4 v4, T5 v5, T6 v6, T7 v7) {
-  return internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7>(v1, v2, v3, v4, v5,
-      v6, v7);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8>
-internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8> Values(T1 v1, T2 v2,
-    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
-  return internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8>(v1, v2, v3, v4,
-      v5, v6, v7, v8);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9>
-internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9> Values(T1 v1, T2 v2,
-    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
-  return internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(v1, v2, v3,
-      v4, v5, v6, v7, v8, v9);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10>
-internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Values(T1 v1,
-    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
-  return internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(v1,
-      v2, v3, v4, v5, v6, v7, v8, v9, v10);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11>
-internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
-    T11> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-    T10 v10, T11 v11) {
-  return internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
-      T11>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12>
-internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-    T12> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-    T10 v10, T11 v11, T12 v12) {
-  return internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13>
-internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
-    T13> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-    T10 v10, T11 v11, T12 v12, T13 v13) {
-  return internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14>
-internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
-  return internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
-      v14);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15>
-internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
-    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
-  return internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
-      v13, v14, v15);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16>
-internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
-    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
-    T16 v16) {
-  return internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
-      v12, v13, v14, v15, v16);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17>
-internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
-    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
-    T16 v16, T17 v17) {
-  return internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
-      v11, v12, v13, v14, v15, v16, v17);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18>
-internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
-    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
-    T16 v16, T17 v17, T18 v18) {
-  return internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
-      v10, v11, v12, v13, v14, v15, v16, v17, v18);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19>
-internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
-    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
-    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) {
-  return internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19>(v1, v2, v3, v4, v5, v6, v7, v8,
-      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20>
-internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20> Values(T1 v1, T2 v2, T3 v3, T4 v4,
-    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
-    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) {
-  return internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20>(v1, v2, v3, v4, v5, v6, v7,
-      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21>
-internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21> Values(T1 v1, T2 v2, T3 v3, T4 v4,
-    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
-    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) {
-  return internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(v1, v2, v3, v4, v5, v6,
-      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22>
-internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22> Values(T1 v1, T2 v2, T3 v3,
-    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
-    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
-    T21 v21, T22 v22) {
-  return internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>(v1, v2, v3, v4,
-      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
-      v20, v21, v22);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23>
-internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> Values(T1 v1, T2 v2,
-    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
-    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
-    T21 v21, T22 v22, T23 v23) {
-  return internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>(v1, v2, v3,
-      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
-      v20, v21, v22, v23);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24>
-internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Values(T1 v1, T2 v2,
-    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
-    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
-    T21 v21, T22 v22, T23 v23, T24 v24) {
-  return internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>(v1, v2,
-      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
-      v19, v20, v21, v22, v23, v24);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25>
-internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Values(T1 v1,
-    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
-    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
-    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) {
-  return internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25>(v1,
-      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
-      v18, v19, v20, v21, v22, v23, v24, v25);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26>
-internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-    T26> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-    T26 v26) {
-  return internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
-      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27>
-internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
-    T27> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-    T26 v26, T27 v27) {
-  return internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
-      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28>
-internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
-    T28> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-    T26 v26, T27 v27, T28 v28) {
-  return internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
-      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
-      v28);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29>
-internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-    T26 v26, T27 v27, T28 v28, T29 v29) {
-  return internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
-      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
-      v27, v28, v29);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30>
-internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
-    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
-    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
-    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) {
-  return internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
-      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
-      v26, v27, v28, v29, v30);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31>
-internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
-    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
-    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
-    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) {
-  return internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
-      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
-      v25, v26, v27, v28, v29, v30, v31);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32>
-internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
-    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
-    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
-    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
-    T32 v32) {
-  return internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
-      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
-      v24, v25, v26, v27, v28, v29, v30, v31, v32);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33>
-internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
-    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
-    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
-    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
-    T32 v32, T33 v33) {
-  return internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33>(v1, v2, v3, v4, v5, v6, v7, v8,
-      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
-      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34>
-internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
-    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
-    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
-    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
-    T31 v31, T32 v32, T33 v33, T34 v34) {
-  return internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34>(v1, v2, v3, v4, v5, v6, v7,
-      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
-      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35>
-internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35> Values(T1 v1, T2 v2, T3 v3, T4 v4,
-    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
-    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
-    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
-    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) {
-  return internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35>(v1, v2, v3, v4, v5, v6,
-      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
-      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36>
-internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36> Values(T1 v1, T2 v2, T3 v3, T4 v4,
-    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
-    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
-    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
-    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) {
-  return internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36>(v1, v2, v3, v4,
-      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
-      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
-      v34, v35, v36);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37>
-internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37> Values(T1 v1, T2 v2, T3 v3,
-    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
-    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
-    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
-    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
-    T37 v37) {
-  return internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37>(v1, v2, v3,
-      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
-      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
-      v34, v35, v36, v37);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38>
-internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Values(T1 v1, T2 v2,
-    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
-    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
-    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
-    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
-    T37 v37, T38 v38) {
-  return internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38>(v1, v2,
-      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
-      v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32,
-      v33, v34, v35, v36, v37, v38);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39>
-internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Values(T1 v1, T2 v2,
-    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
-    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
-    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
-    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
-    T37 v37, T38 v38, T39 v39) {
-  return internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39>(v1,
-      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
-      v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
-      v32, v33, v34, v35, v36, v37, v38, v39);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40>
-internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Values(T1 v1,
-    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
-    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
-    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27,
-    T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35,
-    T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) {
-  return internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
-      T40>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
-      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,
-      v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41>
-internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
-    T41> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) {
-  return internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
-      T40, T41>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
-      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28,
-      v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42>
-internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
-    T42> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
-    T42 v42) {
-  return internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
-      T40, T41, T42>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
-      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
-      v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41,
-      v42);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43>
-internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
-    T43> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
-    T42 v42, T43 v43) {
-  return internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
-      T40, T41, T42, T43>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
-      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
-      v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40,
-      v41, v42, v43);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44>
-internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
-    T44> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
-    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
-    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
-    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
-    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
-    T42 v42, T43 v43, T44 v44) {
-  return internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
-      T40, T41, T42, T43, T44>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
-      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
-      v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,
-      v40, v41, v42, v43, v44);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44, typename T45>
-internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
-    T44, T45> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
-    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
-    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
-    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
-    T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
-    T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) {
-  return internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
-      T40, T41, T42, T43, T44, T45>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
-      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
-      v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38,
-      v39, v40, v41, v42, v43, v44, v45);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44, typename T45,
-    typename T46>
-internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
-    T44, T45, T46> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
-    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
-    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
-    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
-    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
-    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) {
-  return internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
-      T40, T41, T42, T43, T44, T45, T46>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
-      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
-      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
-      v38, v39, v40, v41, v42, v43, v44, v45, v46);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44, typename T45,
-    typename T46, typename T47>
-internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
-    T44, T45, T46, T47> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
-    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
-    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
-    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
-    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
-    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) {
-  return internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
-      T40, T41, T42, T43, T44, T45, T46, T47>(v1, v2, v3, v4, v5, v6, v7, v8,
-      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
-      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
-      v38, v39, v40, v41, v42, v43, v44, v45, v46, v47);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44, typename T45,
-    typename T46, typename T47, typename T48>
-internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
-    T44, T45, T46, T47, T48> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
-    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
-    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
-    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
-    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
-    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47,
-    T48 v48) {
-  return internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
-      T40, T41, T42, T43, T44, T45, T46, T47, T48>(v1, v2, v3, v4, v5, v6, v7,
-      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
-      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36,
-      v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44, typename T45,
-    typename T46, typename T47, typename T48, typename T49>
-internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
-    T44, T45, T46, T47, T48, T49> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
-    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
-    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
-    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
-    T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38,
-    T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46,
-    T47 v47, T48 v48, T49 v49) {
-  return internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
-      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49>(v1, v2, v3, v4, v5, v6,
-      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
-      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35,
-      v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
-    typename T6, typename T7, typename T8, typename T9, typename T10,
-    typename T11, typename T12, typename T13, typename T14, typename T15,
-    typename T16, typename T17, typename T18, typename T19, typename T20,
-    typename T21, typename T22, typename T23, typename T24, typename T25,
-    typename T26, typename T27, typename T28, typename T29, typename T30,
-    typename T31, typename T32, typename T33, typename T34, typename T35,
-    typename T36, typename T37, typename T38, typename T39, typename T40,
-    typename T41, typename T42, typename T43, typename T44, typename T45,
-    typename T46, typename T47, typename T48, typename T49, typename T50>
-internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
-    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
-    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
-    T44, T45, T46, T47, T48, T49, T50> Values(T1 v1, T2 v2, T3 v3, T4 v4,
-    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
-    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
-    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
-    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37,
-    T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45,
-    T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) {
-  return internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
-      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
-      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
-      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>(v1, v2, v3, v4,
-      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
-      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
-      v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47,
-      v48, v49, v50);
+template <typename... T>
+internal::ValueArray<T...> Values(T... v) {
+  return internal::ValueArray<T...>(std::move(v)...);
 }
 
 // Bool() allows generating tests with parameters in a set of (false, true).
@@ -17942,7 +11595,7 @@
 // of multiple flags can be tested when several Bool()'s are combined using
 // Combine() function.
 //
-// In the following example all tests in the test case FlagDependentTest
+// In the following example all tests in the test suite FlagDependentTest
 // will be instantiated twice with parameters false and true.
 //
 // class FlagDependentTest : public testing::TestWithParam<bool> {
@@ -17950,13 +11603,12 @@
 //     external_flag = GetParam();
 //   }
 // }
-// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
+// INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool());
 //
 inline internal::ParamGenerator<bool> Bool() {
   return Values(false, true);
 }
 
-# if GTEST_HAS_COMBINE
 // Combine() allows the user to combine two or more sequences to produce
 // values of a Cartesian product of those sequences' elements.
 //
@@ -17965,217 +11617,138 @@
 //   - returns a generator producing sequences with elements coming from
 //     the Cartesian product of elements from the sequences generated by
 //     gen1, gen2, ..., genN. The sequence elements will have a type of
-//     tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
+//     std::tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
 //     of elements from sequences produces by gen1, gen2, ..., genN.
 //
-// Combine can have up to 10 arguments. This number is currently limited
-// by the maximum number of elements in the tuple implementation used by Google
-// Test.
+// Combine can have up to 10 arguments.
 //
 // Example:
 //
-// This will instantiate tests in test case AnimalTest each one with
+// This will instantiate tests in test suite AnimalTest each one with
 // the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
 // tuple("dog", BLACK), and tuple("dog", WHITE):
 //
 // enum Color { BLACK, GRAY, WHITE };
 // class AnimalTest
-//     : public testing::TestWithParam<tuple<const char*, Color> > {...};
+//     : public testing::TestWithParam<std::tuple<const char*, Color> > {...};
 //
 // TEST_P(AnimalTest, AnimalLooksNice) {...}
 //
-// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
-//                         Combine(Values("cat", "dog"),
-//                                 Values(BLACK, WHITE)));
+// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest,
+//                          Combine(Values("cat", "dog"),
+//                                  Values(BLACK, WHITE)));
 //
 // This will instantiate tests in FlagDependentTest with all variations of two
 // Boolean flags:
 //
 // class FlagDependentTest
-//     : public testing::TestWithParam<tuple<bool, bool> > {
+//     : public testing::TestWithParam<std::tuple<bool, bool> > {
 //   virtual void SetUp() {
 //     // Assigns external_flag_1 and external_flag_2 values from the tuple.
-//     tie(external_flag_1, external_flag_2) = GetParam();
+//     std::tie(external_flag_1, external_flag_2) = GetParam();
 //   }
 // };
 //
 // TEST_P(FlagDependentTest, TestFeature1) {
 //   // Test your code using external_flag_1 and external_flag_2 here.
 // }
-// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
-//                         Combine(Bool(), Bool()));
+// INSTANTIATE_TEST_SUITE_P(TwoBoolSequence, FlagDependentTest,
+//                          Combine(Bool(), Bool()));
 //
-template <typename Generator1, typename Generator2>
-internal::CartesianProductHolder2<Generator1, Generator2> Combine(
-    const Generator1& g1, const Generator2& g2) {
-  return internal::CartesianProductHolder2<Generator1, Generator2>(
-      g1, g2);
+template <typename... Generator>
+internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
+  return internal::CartesianProductHolder<Generator...>(g...);
 }
 
-template <typename Generator1, typename Generator2, typename Generator3>
-internal::CartesianProductHolder3<Generator1, Generator2, Generator3> Combine(
-    const Generator1& g1, const Generator2& g2, const Generator3& g3) {
-  return internal::CartesianProductHolder3<Generator1, Generator2, Generator3>(
-      g1, g2, g3);
-}
+#define TEST_P(test_suite_name, test_name)                                     \
+  class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)                     \
+      : public test_suite_name {                                               \
+   public:                                                                     \
+    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {}                    \
+    virtual void TestBody();                                                   \
+                                                                               \
+   private:                                                                    \
+    static int AddToRegistry() {                                               \
+      ::testing::UnitTest::GetInstance()                                       \
+          ->parameterized_test_registry()                                      \
+          .GetTestSuitePatternHolder<test_suite_name>(                         \
+              #test_suite_name,                                                \
+              ::testing::internal::CodeLocation(__FILE__, __LINE__))           \
+          ->AddTestPattern(                                                    \
+              GTEST_STRINGIFY_(test_suite_name), GTEST_STRINGIFY_(test_name),  \
+              new ::testing::internal::TestMetaFactory<GTEST_TEST_CLASS_NAME_( \
+                  test_suite_name, test_name)>());                             \
+      return 0;                                                                \
+    }                                                                          \
+    static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_;               \
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name,    \
+                                                           test_name));        \
+  };                                                                           \
+  int GTEST_TEST_CLASS_NAME_(test_suite_name,                                  \
+                             test_name)::gtest_registering_dummy_ =            \
+      GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::AddToRegistry();     \
+  void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
 
-template <typename Generator1, typename Generator2, typename Generator3,
-    typename Generator4>
-internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
-    Generator4> Combine(
-    const Generator1& g1, const Generator2& g2, const Generator3& g3,
-        const Generator4& g4) {
-  return internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
-      Generator4>(
-      g1, g2, g3, g4);
-}
-
-template <typename Generator1, typename Generator2, typename Generator3,
-    typename Generator4, typename Generator5>
-internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
-    Generator4, Generator5> Combine(
-    const Generator1& g1, const Generator2& g2, const Generator3& g3,
-        const Generator4& g4, const Generator5& g5) {
-  return internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
-      Generator4, Generator5>(
-      g1, g2, g3, g4, g5);
-}
-
-template <typename Generator1, typename Generator2, typename Generator3,
-    typename Generator4, typename Generator5, typename Generator6>
-internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
-    Generator4, Generator5, Generator6> Combine(
-    const Generator1& g1, const Generator2& g2, const Generator3& g3,
-        const Generator4& g4, const Generator5& g5, const Generator6& g6) {
-  return internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
-      Generator4, Generator5, Generator6>(
-      g1, g2, g3, g4, g5, g6);
-}
-
-template <typename Generator1, typename Generator2, typename Generator3,
-    typename Generator4, typename Generator5, typename Generator6,
-    typename Generator7>
-internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
-    Generator4, Generator5, Generator6, Generator7> Combine(
-    const Generator1& g1, const Generator2& g2, const Generator3& g3,
-        const Generator4& g4, const Generator5& g5, const Generator6& g6,
-        const Generator7& g7) {
-  return internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
-      Generator4, Generator5, Generator6, Generator7>(
-      g1, g2, g3, g4, g5, g6, g7);
-}
-
-template <typename Generator1, typename Generator2, typename Generator3,
-    typename Generator4, typename Generator5, typename Generator6,
-    typename Generator7, typename Generator8>
-internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
-    Generator4, Generator5, Generator6, Generator7, Generator8> Combine(
-    const Generator1& g1, const Generator2& g2, const Generator3& g3,
-        const Generator4& g4, const Generator5& g5, const Generator6& g6,
-        const Generator7& g7, const Generator8& g8) {
-  return internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
-      Generator4, Generator5, Generator6, Generator7, Generator8>(
-      g1, g2, g3, g4, g5, g6, g7, g8);
-}
-
-template <typename Generator1, typename Generator2, typename Generator3,
-    typename Generator4, typename Generator5, typename Generator6,
-    typename Generator7, typename Generator8, typename Generator9>
-internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
-    Generator4, Generator5, Generator6, Generator7, Generator8,
-    Generator9> Combine(
-    const Generator1& g1, const Generator2& g2, const Generator3& g3,
-        const Generator4& g4, const Generator5& g5, const Generator6& g6,
-        const Generator7& g7, const Generator8& g8, const Generator9& g9) {
-  return internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
-      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9>(
-      g1, g2, g3, g4, g5, g6, g7, g8, g9);
-}
-
-template <typename Generator1, typename Generator2, typename Generator3,
-    typename Generator4, typename Generator5, typename Generator6,
-    typename Generator7, typename Generator8, typename Generator9,
-    typename Generator10>
-internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
-    Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
-    Generator10> Combine(
-    const Generator1& g1, const Generator2& g2, const Generator3& g3,
-        const Generator4& g4, const Generator5& g5, const Generator6& g6,
-        const Generator7& g7, const Generator8& g8, const Generator9& g9,
-        const Generator10& g10) {
-  return internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
-      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
-      Generator10>(
-      g1, g2, g3, g4, g5, g6, g7, g8, g9, g10);
-}
-# endif  // GTEST_HAS_COMBINE
-
-
-
-# define TEST_P(test_case_name, test_name) \
-  class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
-      : public test_case_name { \
-   public: \
-    GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
-    virtual void TestBody(); \
-   private: \
-    static int AddToRegistry() { \
-      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
-          GetTestCasePatternHolder<test_case_name>(\
-              #test_case_name, \
-              ::testing::internal::CodeLocation(\
-                  __FILE__, __LINE__))->AddTestPattern(\
-                      #test_case_name, \
-                      #test_name, \
-                      new ::testing::internal::TestMetaFactory< \
-                          GTEST_TEST_CLASS_NAME_(\
-                              test_case_name, test_name)>()); \
-      return 0; \
-    } \
-    static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
-    GTEST_DISALLOW_COPY_AND_ASSIGN_(\
-        GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
-  }; \
-  int GTEST_TEST_CLASS_NAME_(test_case_name, \
-                             test_name)::gtest_registering_dummy_ = \
-      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
-  void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
-
-// The optional last argument to INSTANTIATE_TEST_CASE_P allows the user
-// to specify a function or functor that generates custom test name suffixes
-// based on the test parameters. The function should accept one argument of
-// type testing::TestParamInfo<class ParamType>, and return std::string.
+// The last argument to INSTANTIATE_TEST_SUITE_P allows the user to specify
+// generator and an optional function or functor that generates custom test name
+// suffixes based on the test parameters. Such a function or functor should
+// accept one argument of type testing::TestParamInfo<class ParamType>, and
+// return std::string.
 //
 // testing::PrintToStringParamName is a builtin test suffix generator that
-// returns the value of testing::PrintToString(GetParam()). It does not work
-// for std::string or C strings.
+// returns the value of testing::PrintToString(GetParam()).
 //
 // Note: test names must be non-empty, unique, and may only contain ASCII
-// alphanumeric characters or underscore.
+// alphanumeric characters or underscore. Because PrintToString adds quotes
+// to std::string and C strings, it won't work for these types.
 
-# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator, ...) \
-  ::testing::internal::ParamGenerator<test_case_name::ParamType> \
-      gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
-  ::std::string gtest_##prefix##test_case_name##_EvalGenerateName_( \
-      const ::testing::TestParamInfo<test_case_name::ParamType>& info) { \
-    return ::testing::internal::GetParamNameGen<test_case_name::ParamType> \
-        (__VA_ARGS__)(info); \
-  } \
-  int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
-      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
-          GetTestCasePatternHolder<test_case_name>(\
-              #test_case_name, \
-              ::testing::internal::CodeLocation(\
-                  __FILE__, __LINE__))->AddTestCaseInstantiation(\
-                      #prefix, \
-                      &gtest_##prefix##test_case_name##_EvalGenerator_, \
-                      &gtest_##prefix##test_case_name##_EvalGenerateName_, \
-                      __FILE__, __LINE__)
+#define GTEST_EXPAND_(arg) arg
+#define GTEST_GET_FIRST_(first, ...) first
+#define GTEST_GET_SECOND_(first, second, ...) second
+
+#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...)                \
+  static ::testing::internal::ParamGenerator<test_suite_name::ParamType>      \
+      gtest_##prefix##test_suite_name##_EvalGenerator_() {                    \
+    return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_));        \
+  }                                                                           \
+  static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_(   \
+      const ::testing::TestParamInfo<test_suite_name::ParamType>& info) {     \
+    if (::testing::internal::AlwaysFalse()) {                                 \
+      ::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_(      \
+          __VA_ARGS__,                                                        \
+          ::testing::internal::DefaultParamName<test_suite_name::ParamType>,  \
+          DUMMY_PARAM_)));                                                    \
+      auto t = std::make_tuple(__VA_ARGS__);                                  \
+      static_assert(std::tuple_size<decltype(t)>::value <= 2,                 \
+                    "Too Many Args!");                                        \
+    }                                                                         \
+    return ((GTEST_EXPAND_(GTEST_GET_SECOND_(                                 \
+        __VA_ARGS__,                                                          \
+        ::testing::internal::DefaultParamName<test_suite_name::ParamType>,    \
+        DUMMY_PARAM_))))(info);                                               \
+  }                                                                           \
+  static int gtest_##prefix##test_suite_name##_dummy_                         \
+      GTEST_ATTRIBUTE_UNUSED_ =                                               \
+          ::testing::UnitTest::GetInstance()                                  \
+              ->parameterized_test_registry()                                 \
+              .GetTestSuitePatternHolder<test_suite_name>(                    \
+                  #test_suite_name,                                           \
+                  ::testing::internal::CodeLocation(__FILE__, __LINE__))      \
+              ->AddTestSuiteInstantiation(                                    \
+                  #prefix, &gtest_##prefix##test_suite_name##_EvalGenerator_, \
+                  &gtest_##prefix##test_suite_name##_EvalGenerateName_,       \
+                  __FILE__, __LINE__)
+
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+#define INSTANTIATE_TEST_CASE_P                                            \
+  static_assert(::testing::internal::InstantiateTestCase_P_IsDeprecated(), \
+                "");                                                       \
+  INSTANTIATE_TEST_SUITE_P
+#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
 }  // namespace testing
 
-#endif  // GTEST_HAS_PARAM_TEST
-
 #endif  // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
 // Copyright 2006, Google Inc.
 // All rights reserved.
@@ -18205,10 +11778,10 @@
 // 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: wan@google.com (Zhanyong Wan)
-//
-// Google C++ Testing Framework definitions useful in production code.
+// Google C++ Testing and Mocking Framework definitions useful in production code.
+// GOOGLETEST_CM0003 DO NOT DELETE
 
 #ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
 #define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
@@ -18219,17 +11792,20 @@
 //
 // class MyClass {
 //  private:
-//   void MyMethod();
-//   FRIEND_TEST(MyClassTest, MyMethod);
+//   void PrivateMethod();
+//   FRIEND_TEST(MyClassTest, PrivateMethodWorks);
 // };
 //
 // class MyClassTest : public testing::Test {
 //   // ...
 // };
 //
-// TEST_F(MyClassTest, MyMethod) {
-//   // Can call MyClass::MyMethod() here.
+// TEST_F(MyClassTest, PrivateMethodWorks) {
+//   // Can call MyClass::PrivateMethod() here.
 // }
+//
+// Note: The test class must be in the same namespace as the class being tested.
+// For example, putting MyClassTest in an anonymous namespace will not work.
 
 #define FRIEND_TEST(test_case_name, test_name)\
 friend class test_case_name##_##test_name##_Test
@@ -18264,8 +11840,7 @@
 // (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: mheule@google.com (Markus Heule)
-//
+// GOOGLETEST_CM0001 DO NOT DELETE
 
 #ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
 #define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
@@ -18273,6 +11848,9 @@
 #include <iosfwd>
 #include <vector>
 
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
 namespace testing {
 
 // A copyable object representing the result of a test part (i.e. an
@@ -18286,22 +11864,20 @@
   enum Type {
     kSuccess,          // Succeeded.
     kNonFatalFailure,  // Failed but the test can continue.
-    kFatalFailure      // Failed and the test should be terminated.
+    kFatalFailure,     // Failed and the test should be terminated.
+    kSkip              // Skipped.
   };
 
   // C'tor.  TestPartResult does NOT have a default constructor.
   // Always use this constructor (with parameters) to create a
   // TestPartResult object.
-  TestPartResult(Type a_type,
-                 const char* a_file_name,
-                 int a_line_number,
+  TestPartResult(Type a_type, const char* a_file_name, int a_line_number,
                  const char* a_message)
       : type_(a_type),
-        file_name_(a_file_name == NULL ? "" : a_file_name),
+        file_name_(a_file_name == nullptr ? "" : a_file_name),
         line_number_(a_line_number),
         summary_(ExtractSummary(a_message)),
-        message_(a_message) {
-  }
+        message_(a_message) {}
 
   // Gets the outcome of the test part.
   Type type() const { return type_; }
@@ -18309,7 +11885,7 @@
   // Gets the name of the source file where the test part took place, or
   // NULL if it's unknown.
   const char* file_name() const {
-    return file_name_.empty() ? NULL : file_name_.c_str();
+    return file_name_.empty() ? nullptr : file_name_.c_str();
   }
 
   // Gets the line in the source file where the test part took place,
@@ -18322,18 +11898,21 @@
   // Gets the message associated with the test part.
   const char* message() const { return message_.c_str(); }
 
+  // Returns true iff the test part was skipped.
+  bool skipped() const { return type_ == kSkip; }
+
   // Returns true iff the test part passed.
   bool passed() const { return type_ == kSuccess; }
 
-  // Returns true iff the test part failed.
-  bool failed() const { return type_ != kSuccess; }
-
   // Returns true iff the test part non-fatally failed.
   bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
 
   // Returns true iff the test part fatally failed.
   bool fatally_failed() const { return type_ == kFatalFailure; }
 
+  // Returns true iff the test part failed.
+  bool failed() const { return fatally_failed() || nonfatally_failed(); }
+
  private:
   Type type_;
 
@@ -18378,7 +11957,7 @@
 };
 
 // This interface knows how to report a test part result.
-class TestPartResultReporterInterface {
+class GTEST_API_ TestPartResultReporterInterface {
  public:
   virtual ~TestPartResultReporterInterface() {}
 
@@ -18397,8 +11976,8 @@
     : public TestPartResultReporterInterface {
  public:
   HasNewFatalFailureHelper();
-  virtual ~HasNewFatalFailureHelper();
-  virtual void ReportTestPartResult(const TestPartResult& result);
+  ~HasNewFatalFailureHelper() override;
+  void ReportTestPartResult(const TestPartResult& result) override;
   bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
  private:
   bool has_new_fatal_failure_;
@@ -18411,6 +11990,8 @@
 
 }  // namespace testing
 
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251
+
 #endif  // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
 // Copyright 2008 Google Inc.
 // All Rights Reserved.
@@ -18440,8 +12021,9 @@
 // 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: wan@google.com (Zhanyong Wan)
+
+
+// GOOGLETEST_CM0001 DO NOT DELETE
 
 #ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
 #define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
@@ -18465,18 +12047,18 @@
   T value_;
 };
 
-// Next, associate a list of types with the test case, which will be
+// Next, associate a list of types with the test suite, which will be
 // repeated for each type in the list.  The typedef is necessary for
 // the macro to parse correctly.
 typedef testing::Types<char, int, unsigned int> MyTypes;
-TYPED_TEST_CASE(FooTest, MyTypes);
+TYPED_TEST_SUITE(FooTest, MyTypes);
 
 // If the type list contains only one type, you can write that type
 // directly without Types<...>:
-//   TYPED_TEST_CASE(FooTest, int);
+//   TYPED_TEST_SUITE(FooTest, int);
 
 // Then, use TYPED_TEST() instead of TEST_F() to define as many typed
-// tests for this test case as you want.
+// tests for this test suite as you want.
 TYPED_TEST(FooTest, DoesBlah) {
   // Inside a test, refer to TypeParam to get the type parameter.
   // Since we are inside a derived class template, C++ requires use to
@@ -18496,6 +12078,24 @@
 
 TYPED_TEST(FooTest, HasPropertyA) { ... }
 
+// TYPED_TEST_SUITE takes an optional third argument which allows to specify a
+// class that generates custom test name suffixes based on the type. This should
+// be a class which has a static template function GetName(int index) returning
+// a string for each type. The provided integer index equals the index of the
+// type in the provided type list. In many cases the index can be ignored.
+//
+// For example:
+//   class MyTypeNames {
+//    public:
+//     template <typename T>
+//     static std::string GetName(int) {
+//       if (std::is_same<T, char>()) return "char";
+//       if (std::is_same<T, int>()) return "int";
+//       if (std::is_same<T, unsigned int>()) return "unsignedInt";
+//     }
+//   };
+//   TYPED_TEST_SUITE(FooTest, MyTypes, MyTypeNames);
+
 #endif  // 0
 
 // Type-parameterized tests are abstract test patterns parameterized
@@ -18521,13 +12121,13 @@
   ...
 };
 
-// Next, declare that you will define a type-parameterized test case
+// Next, declare that you will define a type-parameterized test suite
 // (the _P suffix is for "parameterized" or "pattern", whichever you
 // prefer):
-TYPED_TEST_CASE_P(FooTest);
+TYPED_TEST_SUITE_P(FooTest);
 
 // Then, use TYPED_TEST_P() to define as many type-parameterized tests
-// for this type-parameterized test case as you want.
+// for this type-parameterized test suite as you want.
 TYPED_TEST_P(FooTest, DoesBlah) {
   // Inside a test, refer to TypeParam to get the type parameter.
   TypeParam n = 0;
@@ -18538,10 +12138,10 @@
 
 // Now the tricky part: you need to register all test patterns before
 // you can instantiate them.  The first argument of the macro is the
-// test case name; the rest are the names of the tests in this test
+// test suite name; the rest are the names of the tests in this test
 // case.
-REGISTER_TYPED_TEST_CASE_P(FooTest,
-                           DoesBlah, HasPropertyA);
+REGISTER_TYPED_TEST_SUITE_P(FooTest,
+                            DoesBlah, HasPropertyA);
 
 // Finally, you are free to instantiate the pattern with the types you
 // want.  If you put the above code in a header file, you can #include
@@ -18549,14 +12149,19 @@
 //
 // To distinguish different instances of the pattern, the first
 // argument to the INSTANTIATE_* macro is a prefix that will be added
-// to the actual test case name.  Remember to pick unique prefixes for
+// to the actual test suite name.  Remember to pick unique prefixes for
 // different instances.
 typedef testing::Types<char, int, unsigned int> MyTypes;
-INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
+INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
 
 // If the type list contains only one type, you can write that type
 // directly without Types<...>:
-//   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
+//   INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, int);
+//
+// Similar to the optional argument of TYPED_TEST_SUITE above,
+// INSTANTIATE_TEST_SUITE_P takes an optional fourth argument which allows to
+// generate custom names.
+//   INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes, MyTypeNames);
 
 #endif  // 0
 
@@ -18568,35 +12173,56 @@
 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
 //
 // Expands to the name of the typedef for the type parameters of the
-// given test case.
-# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
+// given test suite.
+#define GTEST_TYPE_PARAMS_(TestSuiteName) gtest_type_params_##TestSuiteName##_
+
+// Expands to the name of the typedef for the NameGenerator, responsible for
+// creating the suffixes of the name.
+#define GTEST_NAME_GENERATOR_(TestSuiteName) \
+  gtest_type_params_##TestSuiteName##_NameGenerator
 
 // The 'Types' template argument below must have spaces around it
 // since some compilers may choke on '>>' when passing a template
 // instance (e.g. Types<int>)
-# define TYPED_TEST_CASE(CaseName, Types) \
-  typedef ::testing::internal::TypeList< Types >::type \
-      GTEST_TYPE_PARAMS_(CaseName)
+#define TYPED_TEST_SUITE(CaseName, Types, ...)                           \
+  typedef ::testing::internal::TypeList<Types>::type GTEST_TYPE_PARAMS_( \
+      CaseName);                                                         \
+  typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type  \
+      GTEST_NAME_GENERATOR_(CaseName)
 
-# define TYPED_TEST(CaseName, TestName) \
-  template <typename gtest_TypeParam_> \
-  class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
-      : public CaseName<gtest_TypeParam_> { \
-   private: \
-    typedef CaseName<gtest_TypeParam_> TestFixture; \
-    typedef gtest_TypeParam_ TypeParam; \
-    virtual void TestBody(); \
-  }; \
-  bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
-      ::testing::internal::TypeParameterizedTest< \
-          CaseName, \
-          ::testing::internal::TemplateSel< \
-              GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
-          GTEST_TYPE_PARAMS_(CaseName)>::Register(\
-              "", ::testing::internal::CodeLocation(__FILE__, __LINE__), \
-              #CaseName, #TestName, 0); \
-  template <typename gtest_TypeParam_> \
-  void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
+# define TYPED_TEST(CaseName, TestName)                                       \
+  template <typename gtest_TypeParam_>                                        \
+  class GTEST_TEST_CLASS_NAME_(CaseName, TestName)                            \
+      : public CaseName<gtest_TypeParam_> {                                   \
+   private:                                                                   \
+    typedef CaseName<gtest_TypeParam_> TestFixture;                           \
+    typedef gtest_TypeParam_ TypeParam;                                       \
+    virtual void TestBody();                                                  \
+  };                                                                          \
+  static bool gtest_##CaseName##_##TestName##_registered_                     \
+        GTEST_ATTRIBUTE_UNUSED_ =                                             \
+      ::testing::internal::TypeParameterizedTest<                             \
+          CaseName,                                                           \
+          ::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName,   \
+                                                                  TestName)>, \
+          GTEST_TYPE_PARAMS_(                                                 \
+              CaseName)>::Register("",                                        \
+                                   ::testing::internal::CodeLocation(         \
+                                       __FILE__, __LINE__),                   \
+                                   #CaseName, #TestName, 0,                   \
+                                   ::testing::internal::GenerateNames<        \
+                                       GTEST_NAME_GENERATOR_(CaseName),       \
+                                       GTEST_TYPE_PARAMS_(CaseName)>());      \
+  template <typename gtest_TypeParam_>                                        \
+  void GTEST_TEST_CLASS_NAME_(CaseName,                                       \
+                              TestName)<gtest_TypeParam_>::TestBody()
+
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+#define TYPED_TEST_CASE                                                \
+  static_assert(::testing::internal::TypedTestCaseIsDeprecated(), ""); \
+  TYPED_TEST_SUITE
+#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
 #endif  // GTEST_HAS_TYPED_TEST
 
@@ -18607,73 +12233,104 @@
 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
 //
 // Expands to the namespace name that the type-parameterized tests for
-// the given type-parameterized test case are defined in.  The exact
+// the given type-parameterized test suite are defined in.  The exact
 // name of the namespace is subject to change without notice.
-# define GTEST_CASE_NAMESPACE_(TestCaseName) \
-  gtest_case_##TestCaseName##_
+#define GTEST_SUITE_NAMESPACE_(TestSuiteName) gtest_suite_##TestSuiteName##_
 
 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
 //
 // Expands to the name of the variable used to remember the names of
-// the defined tests in the given test case.
-# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
-  gtest_typed_test_case_p_state_##TestCaseName##_
+// the defined tests in the given test suite.
+#define GTEST_TYPED_TEST_SUITE_P_STATE_(TestSuiteName) \
+  gtest_typed_test_suite_p_state_##TestSuiteName##_
 
 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
 //
 // Expands to the name of the variable used to remember the names of
-// the registered tests in the given test case.
-# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
-  gtest_registered_test_names_##TestCaseName##_
+// the registered tests in the given test suite.
+#define GTEST_REGISTERED_TEST_NAMES_(TestSuiteName) \
+  gtest_registered_test_names_##TestSuiteName##_
 
 // The variables defined in the type-parameterized test macros are
 // static as typically these macros are used in a .h file that can be
 // #included in multiple translation units linked together.
-# define TYPED_TEST_CASE_P(CaseName) \
-  static ::testing::internal::TypedTestCasePState \
-      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
+#define TYPED_TEST_SUITE_P(SuiteName)              \
+  static ::testing::internal::TypedTestSuitePState \
+      GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)
 
-# define TYPED_TEST_P(CaseName, TestName) \
-  namespace GTEST_CASE_NAMESPACE_(CaseName) { \
-  template <typename gtest_TypeParam_> \
-  class TestName : public CaseName<gtest_TypeParam_> { \
-   private: \
-    typedef CaseName<gtest_TypeParam_> TestFixture; \
-    typedef gtest_TypeParam_ TypeParam; \
-    virtual void TestBody(); \
-  }; \
-  static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
-      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
-          __FILE__, __LINE__, #CaseName, #TestName); \
-  } \
-  template <typename gtest_TypeParam_> \
-  void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+#define TYPED_TEST_CASE_P                                                 \
+  static_assert(::testing::internal::TypedTestCase_P_IsDeprecated(), ""); \
+  TYPED_TEST_SUITE_P
+#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
-# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
-  namespace GTEST_CASE_NAMESPACE_(CaseName) { \
-  typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
-  } \
-  static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
-      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
+#define TYPED_TEST_P(SuiteName, TestName)                             \
+  namespace GTEST_SUITE_NAMESPACE_(SuiteName) {                       \
+    template <typename gtest_TypeParam_>                              \
+    class TestName : public SuiteName<gtest_TypeParam_> {             \
+     private:                                                         \
+      typedef SuiteName<gtest_TypeParam_> TestFixture;                \
+      typedef gtest_TypeParam_ TypeParam;                             \
+      virtual void TestBody();                                        \
+    };                                                                \
+    static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
+        GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName(       \
+            __FILE__, __LINE__, #SuiteName, #TestName);               \
+  }                                                                   \
+  template <typename gtest_TypeParam_>                                \
+  void GTEST_SUITE_NAMESPACE_(                                        \
+      SuiteName)::TestName<gtest_TypeParam_>::TestBody()
+
+#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...)                            \
+  namespace GTEST_SUITE_NAMESPACE_(SuiteName) {                                \
+    typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
+  }                                                                            \
+  static const char* const GTEST_REGISTERED_TEST_NAMES_(                       \
+      SuiteName) GTEST_ATTRIBUTE_UNUSED_ =                                     \
+      GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames(    \
           __FILE__, __LINE__, #__VA_ARGS__)
 
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+#define REGISTER_TYPED_TEST_CASE_P                                           \
+  static_assert(::testing::internal::RegisterTypedTestCase_P_IsDeprecated(), \
+                "");                                                         \
+  REGISTER_TYPED_TEST_SUITE_P
+#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
 // The 'Types' template argument below must have spaces around it
 // since some compilers may choke on '>>' when passing a template
 // instance (e.g. Types<int>)
-# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
-  bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
-      ::testing::internal::TypeParameterizedTestCase<CaseName, \
-          GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
-          ::testing::internal::TypeList< Types >::type>::Register(\
-              #Prefix, \
-              ::testing::internal::CodeLocation(__FILE__, __LINE__), \
-              &GTEST_TYPED_TEST_CASE_P_STATE_(CaseName), \
-              #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
+#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...)       \
+  static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ =        \
+      ::testing::internal::TypeParameterizedTestSuite<                      \
+          SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_,    \
+          ::testing::internal::TypeList<Types>::type>::                     \
+          Register(#Prefix,                                                 \
+                   ::testing::internal::CodeLocation(__FILE__, __LINE__),   \
+                   &GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName), #SuiteName, \
+                   GTEST_REGISTERED_TEST_NAMES_(SuiteName),                 \
+                   ::testing::internal::GenerateNames<                      \
+                       ::testing::internal::NameGeneratorSelector<          \
+                           __VA_ARGS__>::type,                              \
+                       ::testing::internal::TypeList<Types>::type>())
+
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+#define INSTANTIATE_TYPED_TEST_CASE_P                                      \
+  static_assert(                                                           \
+      ::testing::internal::InstantiateTypedTestCase_P_IsDeprecated(), ""); \
+  INSTANTIATE_TYPED_TEST_SUITE_P
+#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
 #endif  // GTEST_HAS_TYPED_TEST_P
 
 #endif  // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
 
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
 // Depending on the platform, different string classes are available.
 // On Linux, in addition to ::std::string, Google also makes use of
 // class ::string, which has the same interface as ::std::string, but
@@ -18691,6 +12348,15 @@
 
 namespace testing {
 
+// Silence C4100 (unreferenced formal parameter) and 4805
+// unsafe mix of type 'const int' and type 'const bool'
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable:4805)
+# pragma warning(disable:4100)
+#endif
+
+
 // Declares the flags.
 
 // This flag temporary enables the disabled tests.
@@ -18712,6 +12378,10 @@
 // the tests to run. If the filter is not given all tests are executed.
 GTEST_DECLARE_string_(filter);
 
+// This flag controls whether Google Test installs a signal handler that dumps
+// debugging information when fatal signals are raised.
+GTEST_DECLARE_bool_(install_failure_signal_handler);
+
 // This flag causes the Google Test to list tests. None of the tests listed
 // are actually run if the flag is provided.
 GTEST_DECLARE_bool_(list_tests);
@@ -18724,6 +12394,9 @@
 // test.
 GTEST_DECLARE_bool_(print_time);
 
+// This flags control whether Google Test prints UTF8 characters as text.
+GTEST_DECLARE_bool_(print_utf8);
+
 // This flag specifies the random number seed.
 GTEST_DECLARE_int32_(random_seed);
 
@@ -18744,7 +12417,7 @@
 
 // When this flag is specified, a failed assertion will throw an
 // exception if exceptions are enabled, or exit the program with a
-// non-zero code otherwise.
+// non-zero code otherwise. For use with an external test framework.
 GTEST_DECLARE_bool_(throw_on_failure);
 
 // When this flag is set with a "host:port" string, on supported
@@ -18752,6 +12425,10 @@
 // the specified host machine.
 GTEST_DECLARE_string_(stream_result_to);
 
+#if GTEST_USE_OWN_FLAGFILE_FLAG_
+GTEST_DECLARE_string_(flagfile);
+#endif  // GTEST_USE_OWN_FLAGFILE_FLAG_
+
 // The upper limit for valid stack trace depths.
 const int kMaxStackTraceDepth = 100;
 
@@ -18769,6 +12446,7 @@
 class TestEventRepeater;
 class UnitTestRecordPropertyTestHelper;
 class WindowsDeathTest;
+class FuchsiaDeathTest;
 class UnitTestImpl* GetUnitTestImpl();
 void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
                                     const std::string& message);
@@ -18779,7 +12457,12 @@
 // If we don't forward declare them the compiler might confuse the classes
 // in friendship clauses with same named classes on the scope.
 class Test;
-class TestCase;
+class TestSuite;
+
+// Old API is still available but deprecated
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+using TestCase = TestSuite;
+#endif
 class TestInfo;
 class UnitTest;
 
@@ -18868,7 +12551,9 @@
   // Used in EXPECT_TRUE/FALSE(assertion_result).
   AssertionResult(const AssertionResult& other);
 
+#if defined(_MSC_VER) && _MSC_VER < 1910
   GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)
+#endif
 
   // Used in the EXPECT_TRUE/FALSE(bool_expression).
   //
@@ -18881,11 +12566,14 @@
   explicit AssertionResult(
       const T& success,
       typename internal::EnableIf<
-          !internal::ImplicitlyConvertible<T, AssertionResult>::value>::type*
-          /*enabler*/ = NULL)
+          !std::is_convertible<T, AssertionResult>::value>::type*
+      /*enabler*/
+      = nullptr)
       : success_(success) {}
 
+#if defined(_MSC_VER) && _MSC_VER < 1910
   GTEST_DISABLE_MSC_WARNINGS_POP_()
+#endif
 
   // Assignment operator.
   AssertionResult& operator=(AssertionResult other) {
@@ -18904,9 +12592,8 @@
   // assertion's expectation). When nothing has been streamed into the
   // object, returns an empty string.
   const char* message() const {
-    return message_.get() != NULL ?  message_->c_str() : "";
+    return message_.get() != nullptr ? message_->c_str() : "";
   }
-  // TODO(vladl@google.com): Remove this after making sure no clients use it.
   // Deprecated; please use message() instead.
   const char* failure_message() const { return message(); }
 
@@ -18927,8 +12614,7 @@
  private:
   // Appends the contents of message to message_.
   void AppendMessage(const Message& a_message) {
-    if (message_.get() == NULL)
-      message_.reset(new ::std::string);
+    if (message_.get() == nullptr) message_.reset(new ::std::string);
     message_->append(a_message.GetString().c_str());
   }
 
@@ -18941,7 +12627,7 @@
   // construct is not satisfied with the predicate's outcome.
   // Referenced via a pointer to avoid taking too much stack frame space
   // with test assertions.
-  internal::scoped_ptr< ::std::string> message_;
+  std::unique_ptr< ::std::string> message_;
 };
 
 // Makes a successful assertion result.
@@ -18954,17 +12640,383 @@
 // Deprecated; use AssertionFailure() << msg.
 GTEST_API_ AssertionResult AssertionFailure(const Message& msg);
 
+}  // namespace testing
+
+// Includes the auto-generated header that implements a family of generic
+// predicate assertion macros. This include comes late because it relies on
+// APIs declared above.
+// Copyright 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.
+
+// This file is AUTOMATICALLY GENERATED on 01/02/2019 by command
+// 'gen_gtest_pred_impl.py 5'.  DO NOT EDIT BY HAND!
+//
+// Implements a family of generic predicate assertion macros.
+// GOOGLETEST_CM0001 DO NOT DELETE
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+
+
+namespace testing {
+
+// This header implements a family of generic predicate assertion
+// macros:
+//
+//   ASSERT_PRED_FORMAT1(pred_format, v1)
+//   ASSERT_PRED_FORMAT2(pred_format, v1, v2)
+//   ...
+//
+// where pred_format is a function or functor that takes n (in the
+// case of ASSERT_PRED_FORMATn) values and their source expression
+// text, and returns a testing::AssertionResult.  See the definition
+// of ASSERT_EQ in gtest.h for an example.
+//
+// If you don't care about formatting, you can use the more
+// restrictive version:
+//
+//   ASSERT_PRED1(pred, v1)
+//   ASSERT_PRED2(pred, v1, v2)
+//   ...
+//
+// where pred is an n-ary function or functor that returns bool,
+// and the values v1, v2, ..., must support the << operator for
+// streaming to std::ostream.
+//
+// We also define the EXPECT_* variations.
+//
+// For now we only support predicates whose arity is at most 5.
+// Please email googletestframework@googlegroups.com if you need
+// support for higher arities.
+
+// GTEST_ASSERT_ is the basic statement to which all of the assertions
+// in this file reduce.  Don't use this in your code.
+
+#define GTEST_ASSERT_(expression, on_failure) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const ::testing::AssertionResult gtest_ar = (expression)) \
+    ; \
+  else \
+    on_failure(gtest_ar.failure_message())
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED1.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1>
+AssertionResult AssertPred1Helper(const char* pred_text,
+                                  const char* e1,
+                                  Pred pred,
+                                  const T1& v1) {
+  if (pred(v1)) return AssertionSuccess();
+
+  return AssertionFailure()
+         << pred_text << "(" << e1 << ") evaluates to false, where"
+         << "\n"
+         << e1 << " evaluates to " << ::testing::PrintToString(v1);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, v1), \
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED1.  Don't use
+// this in your code.
+#define GTEST_PRED1_(pred, v1, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \
+                                             #v1, \
+                                             pred, \
+                                             v1), on_failure)
+
+// Unary predicate assertion macros.
+#define EXPECT_PRED_FORMAT1(pred_format, v1) \
+  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED1(pred, v1) \
+  GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT1(pred_format, v1) \
+  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED1(pred, v1) \
+  GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED2.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2>
+AssertionResult AssertPred2Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2) {
+  if (pred(v1, v2)) return AssertionSuccess();
+
+  return AssertionFailure()
+         << pred_text << "(" << e1 << ", " << e2
+         << ") evaluates to false, where"
+         << "\n"
+         << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
+         << e2 << " evaluates to " << ::testing::PrintToString(v2);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED2.  Don't use
+// this in your code.
+#define GTEST_PRED2_(pred, v1, v2, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \
+                                             #v1, \
+                                             #v2, \
+                                             pred, \
+                                             v1, \
+                                             v2), on_failure)
+
+// Binary predicate assertion macros.
+#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
+  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED2(pred, v1, v2) \
+  GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
+  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED2(pred, v1, v2) \
+  GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED3.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2,
+          typename T3>
+AssertionResult AssertPred3Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  const char* e3,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2,
+                                  const T3& v3) {
+  if (pred(v1, v2, v3)) return AssertionSuccess();
+
+  return AssertionFailure()
+         << pred_text << "(" << e1 << ", " << e2 << ", " << e3
+         << ") evaluates to false, where"
+         << "\n"
+         << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
+         << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
+         << e3 << " evaluates to " << ::testing::PrintToString(v3);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED3.  Don't use
+// this in your code.
+#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \
+                                             #v1, \
+                                             #v2, \
+                                             #v3, \
+                                             pred, \
+                                             v1, \
+                                             v2, \
+                                             v3), on_failure)
+
+// Ternary predicate assertion macros.
+#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
+  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED3(pred, v1, v2, v3) \
+  GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
+  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED3(pred, v1, v2, v3) \
+  GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED4.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2,
+          typename T3,
+          typename T4>
+AssertionResult AssertPred4Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  const char* e3,
+                                  const char* e4,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2,
+                                  const T3& v3,
+                                  const T4& v4) {
+  if (pred(v1, v2, v3, v4)) return AssertionSuccess();
+
+  return AssertionFailure()
+         << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
+         << ") evaluates to false, where"
+         << "\n"
+         << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
+         << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
+         << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
+         << e4 << " evaluates to " << ::testing::PrintToString(v4);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED4.  Don't use
+// this in your code.
+#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \
+                                             #v1, \
+                                             #v2, \
+                                             #v3, \
+                                             #v4, \
+                                             pred, \
+                                             v1, \
+                                             v2, \
+                                             v3, \
+                                             v4), on_failure)
+
+// 4-ary predicate assertion macros.
+#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
+  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
+  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
+  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
+  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED5.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2,
+          typename T3,
+          typename T4,
+          typename T5>
+AssertionResult AssertPred5Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  const char* e3,
+                                  const char* e4,
+                                  const char* e5,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2,
+                                  const T3& v3,
+                                  const T4& v4,
+                                  const T5& v5) {
+  if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
+
+  return AssertionFailure()
+         << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
+         << ", " << e5 << ") evaluates to false, where"
+         << "\n"
+         << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
+         << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
+         << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
+         << e4 << " evaluates to " << ::testing::PrintToString(v4) << "\n"
+         << e5 << " evaluates to " << ::testing::PrintToString(v5);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
+  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
+                on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED5.  Don't use
+// this in your code.
+#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\
+  GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \
+                                             #v1, \
+                                             #v2, \
+                                             #v3, \
+                                             #v4, \
+                                             #v5, \
+                                             pred, \
+                                             v1, \
+                                             v2, \
+                                             v3, \
+                                             v4, \
+                                             v5), on_failure)
+
+// 5-ary predicate assertion macros.
+#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
+  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
+  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
+  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
+  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
+
+
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+
+namespace testing {
+
 // The abstract class that all tests inherit from.
 //
-// In Google Test, a unit test program contains one or many TestCases, and
-// each TestCase contains one or many Tests.
+// In Google Test, a unit test program contains one or many TestSuites, and
+// each TestSuite contains one or many Tests.
 //
 // When you define a test using the TEST macro, you don't need to
 // explicitly derive from Test - the TEST macro automatically does
 // this for you.
 //
 // The only time you derive from Test is when defining a test fixture
-// to be used a TEST_F.  For example:
+// to be used in a TEST_F.  For example:
 //
 //   class FooTest : public testing::Test {
 //    protected:
@@ -18981,29 +13033,30 @@
  public:
   friend class TestInfo;
 
-  // Defines types for pointers to functions that set up and tear down
-  // a test case.
-  typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc;
-  typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc;
-
   // The d'tor is virtual as we intend to inherit from Test.
   virtual ~Test();
 
   // Sets up the stuff shared by all tests in this test case.
   //
-  // Google Test will call Foo::SetUpTestCase() before running the first
+  // Google Test will call Foo::SetUpTestSuite() before running the first
   // test in test case Foo.  Hence a sub-class can define its own
-  // SetUpTestCase() method to shadow the one defined in the super
+  // SetUpTestSuite() method to shadow the one defined in the super
   // class.
-  static void SetUpTestCase() {}
+  static void SetUpTestSuite() {}
 
   // Tears down the stuff shared by all tests in this test case.
   //
-  // Google Test will call Foo::TearDownTestCase() after running the last
+  // Google Test will call Foo::TearDownTestSuite() after running the last
   // test in test case Foo.  Hence a sub-class can define its own
-  // TearDownTestCase() method to shadow the one defined in the super
+  // TearDownTestSuite() method to shadow the one defined in the super
   // class.
+  static void TearDownTestSuite() {}
+
+  // Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
   static void TearDownTestCase() {}
+  static void SetUpTestCase() {}
+#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
   // Returns true iff the current test has a fatal failure.
   static bool HasFatalFailure();
@@ -19011,19 +13064,22 @@
   // Returns true iff the current test has a non-fatal failure.
   static bool HasNonfatalFailure();
 
+  // Returns true iff the current test was skipped.
+  static bool IsSkipped();
+
   // Returns true iff the current test has a (either fatal or
   // non-fatal) failure.
   static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }
 
-  // Logs a property for the current test, test case, or for the entire
+  // Logs a property for the current test, test suite, or for the entire
   // invocation of the test program when used outside of the context of a
-  // test case.  Only the last value for a given key is remembered.  These
+  // test suite.  Only the last value for a given key is remembered.  These
   // are public static so they can be called from utility functions that are
   // not members of the test fixture.  Calls to RecordProperty made during
   // lifespan of the test (from the moment its constructor starts to the
   // moment its destructor finishes) will be output in XML as attributes of
   // the <testcase> element.  Properties recorded from fixture's
-  // SetUpTestCase or TearDownTestCase are logged as attributes of the
+  // SetUpTestSuite or TearDownTestSuite are logged as attributes of the
   // corresponding <testsuite> element.  Calls to RecordProperty made in the
   // global context (before or after invocation of RUN_ALL_TESTS and from
   // SetUp/TearDown method of Environment objects registered with Google
@@ -19043,7 +13099,7 @@
 
  private:
   // Returns true iff the current test has the same fixture class as
-  // the first test in the current test case.
+  // the first test in the current test suite.
   static bool HasSameFixtureClass();
 
   // Runs the test after the test fixture has been set up.
@@ -19061,7 +13117,7 @@
   // internal method to avoid clashing with names used in user TESTs.
   void DeleteSelf_() { delete this; }
 
-  const internal::scoped_ptr< GTEST_FLAG_SAVER_ > gtest_flag_saver_;
+  const std::unique_ptr<GTEST_FLAG_SAVER_> gtest_flag_saver_;
 
   // Often a user misspells SetUp() as Setup() and spends a long time
   // wondering why it is never called by Google Test.  The declaration of
@@ -19080,7 +13136,7 @@
   // If you see an error about overriding the following function or
   // about it being private, you have mis-spelled SetUp() as Setup().
   struct Setup_should_be_spelled_SetUp {};
-  virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
+  virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; }
 
   // We disallow copying Tests.
   GTEST_DISALLOW_COPY_AND_ASSIGN_(Test);
@@ -19145,7 +13201,10 @@
   int test_property_count() const;
 
   // Returns true iff the test passed (i.e. no test part failed).
-  bool Passed() const { return !Failed(); }
+  bool Passed() const { return !Skipped() && !Failed(); }
+
+  // Returns true iff the test was skipped.
+  bool Skipped() const;
 
   // Returns true iff the test failed.
   bool Failed() const;
@@ -19159,9 +13218,8 @@
   // Returns the elapsed time, in milliseconds.
   TimeInMillis elapsed_time() const { return elapsed_time_; }
 
-  // Returns the i-th test part result among all the results. i can range
-  // from 0 to test_property_count() - 1. If i is not in that range, aborts
-  // the program.
+  // Returns the i-th test part result among all the results. i can range from 0
+  // to total_part_count() - 1. If i is not in that range, aborts the program.
   const TestPartResult& GetTestPartResult(int i) const;
 
   // Returns the i-th test property. i can range from 0 to
@@ -19171,13 +13229,14 @@
 
  private:
   friend class TestInfo;
-  friend class TestCase;
+  friend class TestSuite;
   friend class UnitTest;
   friend class internal::DefaultGlobalTestPartResultReporter;
   friend class internal::ExecDeathTest;
   friend class internal::TestResultAccessor;
   friend class internal::UnitTestImpl;
   friend class internal::WindowsDeathTest;
+  friend class internal::FuchsiaDeathTest;
 
   // Gets the vector of TestPartResults.
   const std::vector<TestPartResult>& test_part_results() const {
@@ -19202,8 +13261,8 @@
                       const TestProperty& test_property);
 
   // Adds a failure if the key is a reserved attribute of Google Test
-  // testcase tags.  Returns true if the property is valid.
-  // TODO(russr): Validate attribute names are legal and human readable.
+  // testsuite tags.  Returns true if the property is valid.
+  // FIXME: Validate attribute names are legal and human readable.
   static bool ValidateTestProperty(const std::string& xml_element,
                                    const TestProperty& test_property);
 
@@ -19241,7 +13300,7 @@
 
 // A TestInfo object stores the following information about a test:
 //
-//   Test case name
+//   Test suite name
 //   Test name
 //   Whether the test should be run
 //   A function pointer that creates the test object when invoked
@@ -19256,8 +13315,13 @@
   // don't inherit from TestInfo.
   ~TestInfo();
 
-  // Returns the test case name.
-  const char* test_case_name() const { return test_case_name_.c_str(); }
+  // Returns the test suite name.
+  const char* test_suite_name() const { return test_suite_name_.c_str(); }
+
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+  const char* test_case_name() const { return test_suite_name(); }
+#endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
   // Returns the test name.
   const char* name() const { return name_.c_str(); }
@@ -19265,17 +13329,15 @@
   // Returns the name of the parameter type, or NULL if this is not a typed
   // or a type-parameterized test.
   const char* type_param() const {
-    if (type_param_.get() != NULL)
-      return type_param_->c_str();
-    return NULL;
+    if (type_param_.get() != nullptr) return type_param_->c_str();
+    return nullptr;
   }
 
   // Returns the text representation of the value parameter, or NULL if this
   // is not a value-parameterized test.
   const char* value_param() const {
-    if (value_param_.get() != NULL)
-      return value_param_->c_str();
-    return NULL;
+    if (value_param_.get() != nullptr) return value_param_->c_str();
+    return nullptr;
   }
 
   // Returns the file name where this test is defined.
@@ -19284,12 +13346,15 @@
   // Returns the line where this test is defined.
   int line() const { return location_.line; }
 
+  // Return true if this test should not be run because it's in another shard.
+  bool is_in_another_shard() const { return is_in_another_shard_; }
+
   // Returns true if this test should run, that is if the test is not
   // disabled (or it is disabled but the also_run_disabled_tests flag has
   // been specified) and its full name matches the user-specified filter.
   //
   // Google Test allows the user to filter the tests by their full names.
-  // The full name of a test Bar in test case Foo is defined as
+  // The full name of a test Bar in test suite Foo is defined as
   // "Foo.Bar".  Only the tests that match the filter will run.
   //
   // A filter is a colon-separated list of glob (not regex) patterns,
@@ -19304,10 +13369,9 @@
 
   // Returns true iff this test will appear in the XML report.
   bool is_reportable() const {
-    // For now, the XML report includes all tests matching the filter.
-    // In the future, we may trim tests that are excluded because of
-    // sharding.
-    return matches_filter_;
+    // The XML report includes tests matching the filter, excluding those
+    // run in other shards.
+    return matches_filter_ && !is_in_another_shard_;
   }
 
   // Returns the result of the test.
@@ -19318,24 +13382,19 @@
   friend class internal::DefaultDeathTestFactory;
 #endif  // GTEST_HAS_DEATH_TEST
   friend class Test;
-  friend class TestCase;
+  friend class TestSuite;
   friend class internal::UnitTestImpl;
   friend class internal::StreamingListenerTest;
   friend TestInfo* internal::MakeAndRegisterTestInfo(
-      const char* test_case_name,
-      const char* name,
-      const char* type_param,
-      const char* value_param,
-      internal::CodeLocation code_location,
-      internal::TypeId fixture_class_id,
-      Test::SetUpTestCaseFunc set_up_tc,
-      Test::TearDownTestCaseFunc tear_down_tc,
+      const char* test_suite_name, const char* name, const char* type_param,
+      const char* value_param, internal::CodeLocation code_location,
+      internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc,
+      internal::TearDownTestSuiteFunc tear_down_tc,
       internal::TestFactoryBase* factory);
 
   // Constructs a TestInfo object. The newly constructed instance assumes
   // ownership of the factory object.
-  TestInfo(const std::string& test_case_name,
-           const std::string& name,
+  TestInfo(const std::string& test_suite_name, const std::string& name,
            const char* a_type_param,   // NULL if not a type-parameterized test
            const char* a_value_param,  // NULL if not a value-parameterized test
            internal::CodeLocation a_code_location,
@@ -19357,20 +13416,21 @@
   }
 
   // These fields are immutable properties of the test.
-  const std::string test_case_name_;     // Test case name
+  const std::string test_suite_name_;    // test suite name
   const std::string name_;               // Test name
   // Name of the parameter type, or NULL if this is not a typed or a
   // type-parameterized test.
-  const internal::scoped_ptr<const ::std::string> type_param_;
+  const std::unique_ptr<const ::std::string> type_param_;
   // Text representation of the value parameter, or NULL if this is not a
   // value-parameterized test.
-  const internal::scoped_ptr<const ::std::string> value_param_;
+  const std::unique_ptr<const ::std::string> value_param_;
   internal::CodeLocation location_;
   const internal::TypeId fixture_class_id_;   // ID of the test fixture class
   bool should_run_;                 // True iff this test should run
   bool is_disabled_;                // True iff this test is disabled
   bool matches_filter_;             // True if this test matches the
                                     // user-specified filter.
+  bool is_in_another_shard_;        // Will be run in another shard.
   internal::TestFactoryBase* const factory_;  // The factory that creates
                                               // the test object
 
@@ -19381,69 +13441,71 @@
   GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo);
 };
 
-// A test case, which consists of a vector of TestInfos.
+// A test suite, which consists of a vector of TestInfos.
 //
-// TestCase is not copyable.
-class GTEST_API_ TestCase {
+// TestSuite is not copyable.
+class GTEST_API_ TestSuite {
  public:
-  // Creates a TestCase with the given name.
+  // Creates a TestSuite with the given name.
   //
-  // TestCase does NOT have a default constructor.  Always use this
-  // constructor to create a TestCase object.
+  // TestSuite does NOT have a default constructor.  Always use this
+  // constructor to create a TestSuite object.
   //
   // Arguments:
   //
-  //   name:         name of the test case
+  //   name:         name of the test suite
   //   a_type_param: the name of the test's type parameter, or NULL if
   //                 this is not a type-parameterized test.
-  //   set_up_tc:    pointer to the function that sets up the test case
-  //   tear_down_tc: pointer to the function that tears down the test case
-  TestCase(const char* name, const char* a_type_param,
-           Test::SetUpTestCaseFunc set_up_tc,
-           Test::TearDownTestCaseFunc tear_down_tc);
+  //   set_up_tc:    pointer to the function that sets up the test suite
+  //   tear_down_tc: pointer to the function that tears down the test suite
+  TestSuite(const char* name, const char* a_type_param,
+            internal::SetUpTestSuiteFunc set_up_tc,
+            internal::TearDownTestSuiteFunc tear_down_tc);
 
-  // Destructor of TestCase.
-  virtual ~TestCase();
+  // Destructor of TestSuite.
+  virtual ~TestSuite();
 
-  // Gets the name of the TestCase.
+  // Gets the name of the TestSuite.
   const char* name() const { return name_.c_str(); }
 
   // Returns the name of the parameter type, or NULL if this is not a
-  // type-parameterized test case.
+  // type-parameterized test suite.
   const char* type_param() const {
-    if (type_param_.get() != NULL)
-      return type_param_->c_str();
-    return NULL;
+    if (type_param_.get() != nullptr) return type_param_->c_str();
+    return nullptr;
   }
 
-  // Returns true if any test in this test case should run.
+  // Returns true if any test in this test suite should run.
   bool should_run() const { return should_run_; }
 
-  // Gets the number of successful tests in this test case.
+  // Gets the number of successful tests in this test suite.
   int successful_test_count() const;
 
-  // Gets the number of failed tests in this test case.
+  // Gets the number of skipped tests in this test suite.
+  int skipped_test_count() const;
+
+  // Gets the number of failed tests in this test suite.
   int failed_test_count() const;
 
   // Gets the number of disabled tests that will be reported in the XML report.
   int reportable_disabled_test_count() const;
 
-  // Gets the number of disabled tests in this test case.
+  // Gets the number of disabled tests in this test suite.
   int disabled_test_count() const;
 
   // Gets the number of tests to be printed in the XML report.
   int reportable_test_count() const;
 
-  // Get the number of tests in this test case that should run.
+  // Get the number of tests in this test suite that should run.
   int test_to_run_count() const;
 
-  // Gets the number of all tests in this test case.
+  // Gets the number of all tests in this test suite.
   int total_test_count() const;
 
-  // Returns true iff the test case passed.
+  // Returns true iff the test suite passed.
   bool Passed() const { return !Failed(); }
 
-  // Returns true iff the test case failed.
+  // Returns true iff the test suite failed.
   bool Failed() const { return failed_test_count() > 0; }
 
   // Returns the elapsed time, in milliseconds.
@@ -19454,17 +13516,17 @@
   const TestInfo* GetTestInfo(int i) const;
 
   // Returns the TestResult that holds test properties recorded during
-  // execution of SetUpTestCase and TearDownTestCase.
+  // execution of SetUpTestSuite and TearDownTestSuite.
   const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; }
 
  private:
   friend class Test;
   friend class internal::UnitTestImpl;
 
-  // Gets the (mutable) vector of TestInfos in this TestCase.
+  // Gets the (mutable) vector of TestInfos in this TestSuite.
   std::vector<TestInfo*>& test_info_list() { return test_info_list_; }
 
-  // Gets the (immutable) vector of TestInfos in this TestCase.
+  // Gets the (immutable) vector of TestInfos in this TestSuite.
   const std::vector<TestInfo*>& test_info_list() const {
     return test_info_list_;
   }
@@ -19476,34 +13538,47 @@
   // Sets the should_run member.
   void set_should_run(bool should) { should_run_ = should; }
 
-  // Adds a TestInfo to this test case.  Will delete the TestInfo upon
-  // destruction of the TestCase object.
+  // Adds a TestInfo to this test suite.  Will delete the TestInfo upon
+  // destruction of the TestSuite object.
   void AddTestInfo(TestInfo * test_info);
 
-  // Clears the results of all tests in this test case.
+  // Clears the results of all tests in this test suite.
   void ClearResult();
 
-  // Clears the results of all tests in the given test case.
-  static void ClearTestCaseResult(TestCase* test_case) {
-    test_case->ClearResult();
+  // Clears the results of all tests in the given test suite.
+  static void ClearTestSuiteResult(TestSuite* test_suite) {
+    test_suite->ClearResult();
   }
 
-  // Runs every test in this TestCase.
+  // Runs every test in this TestSuite.
   void Run();
 
-  // Runs SetUpTestCase() for this TestCase.  This wrapper is needed
-  // for catching exceptions thrown from SetUpTestCase().
-  void RunSetUpTestCase() { (*set_up_tc_)(); }
+  // Runs SetUpTestSuite() for this TestSuite.  This wrapper is needed
+  // for catching exceptions thrown from SetUpTestSuite().
+  void RunSetUpTestSuite() {
+    if (set_up_tc_ != nullptr) {
+      (*set_up_tc_)();
+    }
+  }
 
-  // Runs TearDownTestCase() for this TestCase.  This wrapper is
-  // needed for catching exceptions thrown from TearDownTestCase().
-  void RunTearDownTestCase() { (*tear_down_tc_)(); }
+  // Runs TearDownTestSuite() for this TestSuite.  This wrapper is
+  // needed for catching exceptions thrown from TearDownTestSuite().
+  void RunTearDownTestSuite() {
+    if (tear_down_tc_ != nullptr) {
+      (*tear_down_tc_)();
+    }
+  }
 
   // Returns true iff test passed.
   static bool TestPassed(const TestInfo* test_info) {
     return test_info->should_run() && test_info->result()->Passed();
   }
 
+  // Returns true iff test skipped.
+  static bool TestSkipped(const TestInfo* test_info) {
+    return test_info->should_run() && test_info->result()->Skipped();
+  }
+
   // Returns true iff test failed.
   static bool TestFailed(const TestInfo* test_info) {
     return test_info->should_run() && test_info->result()->Failed();
@@ -19530,17 +13605,17 @@
     return test_info->should_run();
   }
 
-  // Shuffles the tests in this test case.
+  // Shuffles the tests in this test suite.
   void ShuffleTests(internal::Random* random);
 
   // Restores the test order to before the first shuffle.
   void UnshuffleTests();
 
-  // Name of the test case.
+  // Name of the test suite.
   std::string name_;
   // Name of the parameter type, or NULL if this is not a typed or a
   // type-parameterized test.
-  const internal::scoped_ptr<const ::std::string> type_param_;
+  const std::unique_ptr<const ::std::string> type_param_;
   // The vector of TestInfos in their original order.  It owns the
   // elements in the vector.
   std::vector<TestInfo*> test_info_list_;
@@ -19548,20 +13623,20 @@
   // shuffling and restoring the test order.  The i-th element in this
   // vector is the index of the i-th test in the shuffled test list.
   std::vector<int> test_indices_;
-  // Pointer to the function that sets up the test case.
-  Test::SetUpTestCaseFunc set_up_tc_;
-  // Pointer to the function that tears down the test case.
-  Test::TearDownTestCaseFunc tear_down_tc_;
-  // True iff any test in this test case should run.
+  // Pointer to the function that sets up the test suite.
+  internal::SetUpTestSuiteFunc set_up_tc_;
+  // Pointer to the function that tears down the test suite.
+  internal::TearDownTestSuiteFunc tear_down_tc_;
+  // True iff any test in this test suite should run.
   bool should_run_;
   // Elapsed time, in milliseconds.
   TimeInMillis elapsed_time_;
-  // Holds test properties recorded during execution of SetUpTestCase and
-  // TearDownTestCase.
+  // Holds test properties recorded during execution of SetUpTestSuite and
+  // TearDownTestSuite.
   TestResult ad_hoc_test_result_;
 
-  // We disallow copying TestCases.
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase);
+  // We disallow copying TestSuites.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestSuite);
 };
 
 // An Environment object is capable of setting up and tearing down an
@@ -19592,9 +13667,21 @@
   // If you see an error about overriding the following function or
   // about it being private, you have mis-spelled SetUp() as Setup().
   struct Setup_should_be_spelled_SetUp {};
-  virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
+  virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; }
 };
 
+#if GTEST_HAS_EXCEPTIONS
+
+// Exception which can be thrown from TestEventListener::OnTestPartResult.
+class GTEST_API_ AssertionException
+    : public internal::GoogleTestFailureException {
+ public:
+  explicit AssertionException(const TestPartResult& result)
+      : GoogleTestFailureException(result) {}
+};
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
 // The interface for tracing execution of tests. The methods are organized in
 // the order the corresponding events are fired.
 class TestEventListener {
@@ -19616,20 +13703,32 @@
   // Fired after environment set-up for each iteration of tests ends.
   virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;
 
-  // Fired before the test case starts.
-  virtual void OnTestCaseStart(const TestCase& test_case) = 0;
+  // Fired before the test suite starts.
+  virtual void OnTestSuiteStart(const TestSuite& /*test_suite*/) {}
+
+  //  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+  virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
   // Fired before the test starts.
   virtual void OnTestStart(const TestInfo& test_info) = 0;
 
   // Fired after a failed assertion or a SUCCEED() invocation.
+  // If you want to throw an exception from this function to skip to the next
+  // TEST, it must be AssertionException defined above, or inherited from it.
   virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;
 
   // Fired after the test ends.
   virtual void OnTestEnd(const TestInfo& test_info) = 0;
 
-  // Fired after the test case ends.
-  virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
+  // Fired after the test suite ends.
+  virtual void OnTestSuiteEnd(const TestSuite& /*test_suite*/) {}
+
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+  virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
   // Fired before environment tear-down for each iteration of tests starts.
   virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;
@@ -19652,21 +13751,30 @@
 // above.
 class EmptyTestEventListener : public TestEventListener {
  public:
-  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
-  virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
-                                    int /*iteration*/) {}
-  virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {}
-  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
-  virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
-  virtual void OnTestStart(const TestInfo& /*test_info*/) {}
-  virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {}
-  virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
-  virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
-  virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {}
-  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
-  virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
-                                  int /*iteration*/) {}
-  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+  void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
+  void OnTestIterationStart(const UnitTest& /*unit_test*/,
+                            int /*iteration*/) override {}
+  void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override {}
+  void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {}
+  void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {}
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+  void OnTestCaseStart(const TestCase& /*test_case*/) override {}
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
+  void OnTestStart(const TestInfo& /*test_info*/) override {}
+  void OnTestPartResult(const TestPartResult& /*test_part_result*/) override {}
+  void OnTestEnd(const TestInfo& /*test_info*/) override {}
+  void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+  void OnTestCaseEnd(const TestCase& /*test_case*/) override {}
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
+  void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override {}
+  void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {}
+  void OnTestIterationEnd(const UnitTest& /*unit_test*/,
+                          int /*iteration*/) override {}
+  void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
 };
 
 // TestEventListeners lets users add listeners to track events in Google Test.
@@ -19706,7 +13814,7 @@
   }
 
  private:
-  friend class TestCase;
+  friend class TestSuite;
   friend class TestInfo;
   friend class internal::DefaultGlobalTestPartResultReporter;
   friend class internal::NoExecDeathTest;
@@ -19747,7 +13855,7 @@
   GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners);
 };
 
-// A UnitTest consists of a vector of TestCases.
+// A UnitTest consists of a vector of TestSuites.
 //
 // This is a singleton class.  The only instance of UnitTest is
 // created when UnitTest::GetInstance() is first called.  This
@@ -19776,10 +13884,14 @@
   // was executed.  The UnitTest object owns the string.
   const char* original_working_dir() const;
 
-  // Returns the TestCase object for the test that's currently running,
+  // Returns the TestSuite object for the test that's currently running,
   // or NULL if no test is running.
-  const TestCase* current_test_case() const
-      GTEST_LOCK_EXCLUDED_(mutex_);
+  const TestSuite* current_test_suite() const GTEST_LOCK_EXCLUDED_(mutex_);
+
+// Legacy API is still available but deprecated
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+  const TestCase* current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_);
+#endif
 
   // Returns the TestInfo object for the test that's currently running,
   // or NULL if no test is running.
@@ -19789,31 +13901,40 @@
   // Returns the random seed used at the start of the current test run.
   int random_seed() const;
 
-#if GTEST_HAS_PARAM_TEST
-  // Returns the ParameterizedTestCaseRegistry object used to keep track of
+  // Returns the ParameterizedTestSuiteRegistry object used to keep track of
   // value-parameterized tests and instantiate and register them.
   //
   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
-  internal::ParameterizedTestCaseRegistry& parameterized_test_registry()
+  internal::ParameterizedTestSuiteRegistry& parameterized_test_registry()
       GTEST_LOCK_EXCLUDED_(mutex_);
-#endif  // GTEST_HAS_PARAM_TEST
 
-  // Gets the number of successful test cases.
-  int successful_test_case_count() const;
+  // Gets the number of successful test suites.
+  int successful_test_suite_count() const;
 
-  // Gets the number of failed test cases.
-  int failed_test_case_count() const;
+  // Gets the number of failed test suites.
+  int failed_test_suite_count() const;
 
-  // Gets the number of all test cases.
-  int total_test_case_count() const;
+  // Gets the number of all test suites.
+  int total_test_suite_count() const;
 
-  // Gets the number of all test cases that contain at least one test
+  // Gets the number of all test suites that contain at least one test
   // that should run.
+  int test_suite_to_run_count() const;
+
+  //  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+  int successful_test_case_count() const;
+  int failed_test_case_count() const;
+  int total_test_case_count() const;
   int test_case_to_run_count() const;
+#endif  //  EMOVE_LEGACY_TEST_CASEAPI
 
   // Gets the number of successful tests.
   int successful_test_count() const;
 
+  // Gets the number of skipped tests.
+  int skipped_test_count() const;
+
   // Gets the number of failed tests.
   int failed_test_count() const;
 
@@ -19839,19 +13960,24 @@
   // Gets the elapsed time, in milliseconds.
   TimeInMillis elapsed_time() const;
 
-  // Returns true iff the unit test passed (i.e. all test cases passed).
+  // Returns true iff the unit test passed (i.e. all test suites passed).
   bool Passed() const;
 
-  // Returns true iff the unit test failed (i.e. some test case failed
+  // Returns true iff the unit test failed (i.e. some test suite failed
   // or something outside of all tests failed).
   bool Failed() const;
 
-  // Gets the i-th test case among all the test cases. i can range from 0 to
-  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  // Gets the i-th test suite among all the test suites. i can range from 0 to
+  // total_test_suite_count() - 1. If i is not in that range, returns NULL.
+  const TestSuite* GetTestSuite(int i) const;
+
+//  Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
   const TestCase* GetTestCase(int i) const;
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
   // Returns the TestResult containing information on test failures and
-  // properties logged outside of individual test cases.
+  // properties logged outside of individual test suites.
   const TestResult& ad_hoc_test_result() const;
 
   // Returns the list of event listeners that can be used to track events
@@ -19882,25 +14008,25 @@
       GTEST_LOCK_EXCLUDED_(mutex_);
 
   // Adds a TestProperty to the current TestResult object when invoked from
-  // inside a test, to current TestCase's ad_hoc_test_result_ when invoked
-  // from SetUpTestCase or TearDownTestCase, or to the global property set
+  // inside a test, to current TestSuite's ad_hoc_test_result_ when invoked
+  // from SetUpTestSuite or TearDownTestSuite, or to the global property set
   // when invoked elsewhere.  If the result already contains a property with
   // the same key, the value will be updated.
   void RecordProperty(const std::string& key, const std::string& value);
 
-  // Gets the i-th test case among all the test cases. i can range from 0 to
-  // total_test_case_count() - 1. If i is not in that range, returns NULL.
-  TestCase* GetMutableTestCase(int i);
+  // Gets the i-th test suite among all the test suites. i can range from 0 to
+  // total_test_suite_count() - 1. If i is not in that range, returns NULL.
+  TestSuite* GetMutableTestSuite(int i);
 
   // Accessors for the implementation object.
   internal::UnitTestImpl* impl() { return impl_; }
   const internal::UnitTestImpl* impl() const { return impl_; }
 
-  // These classes and funcions are friends as they need to access private
+  // These classes and functions are friends as they need to access private
   // members of UnitTest.
+  friend class ScopedTrace;
   friend class Test;
   friend class internal::AssertHelper;
-  friend class internal::ScopedTrace;
   friend class internal::StreamingListenerTest;
   friend class internal::UnitTestRecordPropertyTestHelper;
   friend Environment* AddGlobalTestEnvironment(Environment* env);
@@ -19975,6 +14101,10 @@
 // UNICODE mode.
 GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);
 
+// This overloaded version can be used on Arduino/embedded platforms where
+// there is no argc/argv.
+GTEST_API_ void InitGoogleTest();
+
 namespace internal {
 
 // Separate the error generating code from the code path to reduce the stack
@@ -19991,17 +14121,22 @@
                    false);
 }
 
+// This block of code defines operator==/!=
+// to block lexical scope lookup.
+// It prevents using invalid operator==/!= defined at namespace scope.
+struct faketype {};
+inline bool operator==(faketype, faketype) { return true; }
+inline bool operator!=(faketype, faketype) { return false; }
+
 // The helper function for {ASSERT|EXPECT}_EQ.
 template <typename T1, typename T2>
 AssertionResult CmpHelperEQ(const char* lhs_expression,
                             const char* rhs_expression,
                             const T1& lhs,
                             const T2& rhs) {
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4389 /* signed/unsigned mismatch */)
   if (lhs == rhs) {
     return AssertionSuccess();
   }
-GTEST_DISABLE_MSC_WARNINGS_POP_()
 
   return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs);
 }
@@ -20055,16 +14190,14 @@
   // EXPECT_EQ(false, a_bool).
   template <typename T1, typename T2>
   static AssertionResult Compare(
-      const char* lhs_expression,
-      const char* rhs_expression,
-      const T1& lhs,
+      const char* lhs_expression, const char* rhs_expression, const T1& lhs,
       const T2& rhs,
       // The following line prevents this overload from being considered if T2
       // is not a pointer type.  We need this because ASSERT_EQ(NULL, my_ptr)
       // expands to Compare("", "", NULL, my_ptr), which requires a conversion
       // to match the Secret* in the other overload, which would otherwise make
       // this template match better.
-      typename EnableIf<!is_pointer<T2>::value>::type* = 0) {
+      typename EnableIf<!std::is_pointer<T2>::value>::type* = nullptr) {
     return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);
   }
 
@@ -20083,8 +14216,8 @@
       Secret* /* lhs (NULL) */,
       T* rhs) {
     // We already know that 'lhs' is a null pointer.
-    return CmpHelperEQ(lhs_expression, rhs_expression,
-                       static_cast<T*>(NULL), rhs);
+    return CmpHelperEQ(lhs_expression, rhs_expression, static_cast<T*>(nullptr),
+                       rhs);
   }
 };
 
@@ -20313,9 +14446,14 @@
   GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);
 };
 
+enum GTestColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW };
+
+GTEST_API_ GTEST_ATTRIBUTE_PRINTF_(2, 3) void ColoredPrintf(GTestColor color,
+                                                            const char* fmt,
+                                                            ...);
+
 }  // namespace internal
 
-#if GTEST_HAS_PARAM_TEST
 // The pure interface class that all value-parameterized tests inherit from.
 // A value-parameterized class must inherit from both ::testing::Test and
 // ::testing::WithParamInterface. In most cases that just means inheriting
@@ -20333,13 +14471,13 @@
 //   FooTest() {
 //     // Can use GetParam() here.
 //   }
-//   virtual ~FooTest() {
+//   ~FooTest() override {
 //     // Can use GetParam() here.
 //   }
-//   virtual void SetUp() {
+//   void SetUp() override {
 //     // Can use GetParam() here.
 //   }
-//   virtual void TearDown {
+//   void TearDown override {
 //     // Can use GetParam() here.
 //   }
 // };
@@ -20348,7 +14486,7 @@
 //   Foo foo;
 //   ASSERT_TRUE(foo.DoesBar(GetParam()));
 // }
-// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
+// INSTANTIATE_TEST_SUITE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
 
 template <typename T>
 class WithParamInterface {
@@ -20357,12 +14495,9 @@
   virtual ~WithParamInterface() {}
 
   // The current parameter value. Is also available in the test fixture's
-  // constructor. This member function is non-static, even though it only
-  // references static data, to reduce the opportunity for incorrect uses
-  // like writing 'WithParamInterface<bool>::GetParam()' for a test that
-  // uses a fixture whose parameter type is int.
-  const ParamType& GetParam() const {
-    GTEST_CHECK_(parameter_ != NULL)
+  // constructor.
+  static const ParamType& GetParam() {
+    GTEST_CHECK_(parameter_ != nullptr)
         << "GetParam() can only be called inside a value-parameterized test "
         << "-- did you intend to write TEST_P instead of TEST_F?";
     return *parameter_;
@@ -20383,7 +14518,7 @@
 };
 
 template <typename T>
-const T* WithParamInterface<T>::parameter_ = NULL;
+const T* WithParamInterface<T>::parameter_ = nullptr;
 
 // Most value-parameterized classes can ignore the existence of
 // WithParamInterface, and can just inherit from ::testing::TestWithParam.
@@ -20392,10 +14527,13 @@
 class TestWithParam : public Test, public WithParamInterface<T> {
 };
 
-#endif  // GTEST_HAS_PARAM_TEST
-
 // Macros for indicating success/failure in test code.
 
+// Skips test in runtime.
+// Skipping test aborts current function.
+// Skipped tests are neither successful nor failed.
+#define GTEST_SKIP() GTEST_SKIP_("Skipped")
+
 // ADD_FAILURE unconditionally adds a failure to the current test.
 // SUCCEED generates a success - it doesn't automatically make the
 // current test successful, as a test is only successful when it has
@@ -20466,379 +14604,18 @@
 // AssertionResult. For more information on how to use AssertionResult with
 // these macros see comments on that class.
 #define EXPECT_TRUE(condition) \
-  GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \
+  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
                       GTEST_NONFATAL_FAILURE_)
 #define EXPECT_FALSE(condition) \
   GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
                       GTEST_NONFATAL_FAILURE_)
 #define ASSERT_TRUE(condition) \
-  GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \
+  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
                       GTEST_FATAL_FAILURE_)
 #define ASSERT_FALSE(condition) \
   GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
                       GTEST_FATAL_FAILURE_)
 
-// Includes the auto-generated header that implements a family of
-// generic predicate assertion macros.
-// Copyright 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.
-
-// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command
-// 'gen_gtest_pred_impl.py 5'.  DO NOT EDIT BY HAND!
-//
-// Implements a family of generic predicate assertion macros.
-
-#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
-#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
-
-// Makes sure this header is not included before gtest.h.
-#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
-# error Do not include gtest_pred_impl.h directly.  Include gtest.h instead.
-#endif  // GTEST_INCLUDE_GTEST_GTEST_H_
-
-// This header implements a family of generic predicate assertion
-// macros:
-//
-//   ASSERT_PRED_FORMAT1(pred_format, v1)
-//   ASSERT_PRED_FORMAT2(pred_format, v1, v2)
-//   ...
-//
-// where pred_format is a function or functor that takes n (in the
-// case of ASSERT_PRED_FORMATn) values and their source expression
-// text, and returns a testing::AssertionResult.  See the definition
-// of ASSERT_EQ in gtest.h for an example.
-//
-// If you don't care about formatting, you can use the more
-// restrictive version:
-//
-//   ASSERT_PRED1(pred, v1)
-//   ASSERT_PRED2(pred, v1, v2)
-//   ...
-//
-// where pred is an n-ary function or functor that returns bool,
-// and the values v1, v2, ..., must support the << operator for
-// streaming to std::ostream.
-//
-// We also define the EXPECT_* variations.
-//
-// For now we only support predicates whose arity is at most 5.
-// Please email googletestframework@googlegroups.com if you need
-// support for higher arities.
-
-// GTEST_ASSERT_ is the basic statement to which all of the assertions
-// in this file reduce.  Don't use this in your code.
-
-#define GTEST_ASSERT_(expression, on_failure) \
-  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
-  if (const ::testing::AssertionResult gtest_ar = (expression)) \
-    ; \
-  else \
-    on_failure(gtest_ar.failure_message())
-
-
-// Helper function for implementing {EXPECT|ASSERT}_PRED1.  Don't use
-// this in your code.
-template <typename Pred,
-          typename T1>
-AssertionResult AssertPred1Helper(const char* pred_text,
-                                  const char* e1,
-                                  Pred pred,
-                                  const T1& v1) {
-  if (pred(v1)) return AssertionSuccess();
-
-  return AssertionFailure() << pred_text << "("
-                            << e1 << ") evaluates to false, where"
-                            << "\n" << e1 << " evaluates to " << v1;
-}
-
-// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
-// Don't use this in your code.
-#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
-  GTEST_ASSERT_(pred_format(#v1, v1), \
-                on_failure)
-
-// Internal macro for implementing {EXPECT|ASSERT}_PRED1.  Don't use
-// this in your code.
-#define GTEST_PRED1_(pred, v1, on_failure)\
-  GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \
-                                             #v1, \
-                                             pred, \
-                                             v1), on_failure)
-
-// Unary predicate assertion macros.
-#define EXPECT_PRED_FORMAT1(pred_format, v1) \
-  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
-#define EXPECT_PRED1(pred, v1) \
-  GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
-#define ASSERT_PRED_FORMAT1(pred_format, v1) \
-  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
-#define ASSERT_PRED1(pred, v1) \
-  GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
-
-
-
-// Helper function for implementing {EXPECT|ASSERT}_PRED2.  Don't use
-// this in your code.
-template <typename Pred,
-          typename T1,
-          typename T2>
-AssertionResult AssertPred2Helper(const char* pred_text,
-                                  const char* e1,
-                                  const char* e2,
-                                  Pred pred,
-                                  const T1& v1,
-                                  const T2& v2) {
-  if (pred(v1, v2)) return AssertionSuccess();
-
-  return AssertionFailure() << pred_text << "("
-                            << e1 << ", "
-                            << e2 << ") evaluates to false, where"
-                            << "\n" << e1 << " evaluates to " << v1
-                            << "\n" << e2 << " evaluates to " << v2;
-}
-
-// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
-// Don't use this in your code.
-#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
-  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \
-                on_failure)
-
-// Internal macro for implementing {EXPECT|ASSERT}_PRED2.  Don't use
-// this in your code.
-#define GTEST_PRED2_(pred, v1, v2, on_failure)\
-  GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \
-                                             #v1, \
-                                             #v2, \
-                                             pred, \
-                                             v1, \
-                                             v2), on_failure)
-
-// Binary predicate assertion macros.
-#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
-  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
-#define EXPECT_PRED2(pred, v1, v2) \
-  GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
-#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
-  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
-#define ASSERT_PRED2(pred, v1, v2) \
-  GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
-
-
-
-// Helper function for implementing {EXPECT|ASSERT}_PRED3.  Don't use
-// this in your code.
-template <typename Pred,
-          typename T1,
-          typename T2,
-          typename T3>
-AssertionResult AssertPred3Helper(const char* pred_text,
-                                  const char* e1,
-                                  const char* e2,
-                                  const char* e3,
-                                  Pred pred,
-                                  const T1& v1,
-                                  const T2& v2,
-                                  const T3& v3) {
-  if (pred(v1, v2, v3)) return AssertionSuccess();
-
-  return AssertionFailure() << pred_text << "("
-                            << e1 << ", "
-                            << e2 << ", "
-                            << e3 << ") evaluates to false, where"
-                            << "\n" << e1 << " evaluates to " << v1
-                            << "\n" << e2 << " evaluates to " << v2
-                            << "\n" << e3 << " evaluates to " << v3;
-}
-
-// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
-// Don't use this in your code.
-#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
-  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \
-                on_failure)
-
-// Internal macro for implementing {EXPECT|ASSERT}_PRED3.  Don't use
-// this in your code.
-#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\
-  GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \
-                                             #v1, \
-                                             #v2, \
-                                             #v3, \
-                                             pred, \
-                                             v1, \
-                                             v2, \
-                                             v3), on_failure)
-
-// Ternary predicate assertion macros.
-#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
-  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
-#define EXPECT_PRED3(pred, v1, v2, v3) \
-  GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
-#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
-  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
-#define ASSERT_PRED3(pred, v1, v2, v3) \
-  GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
-
-
-
-// Helper function for implementing {EXPECT|ASSERT}_PRED4.  Don't use
-// this in your code.
-template <typename Pred,
-          typename T1,
-          typename T2,
-          typename T3,
-          typename T4>
-AssertionResult AssertPred4Helper(const char* pred_text,
-                                  const char* e1,
-                                  const char* e2,
-                                  const char* e3,
-                                  const char* e4,
-                                  Pred pred,
-                                  const T1& v1,
-                                  const T2& v2,
-                                  const T3& v3,
-                                  const T4& v4) {
-  if (pred(v1, v2, v3, v4)) return AssertionSuccess();
-
-  return AssertionFailure() << pred_text << "("
-                            << e1 << ", "
-                            << e2 << ", "
-                            << e3 << ", "
-                            << e4 << ") evaluates to false, where"
-                            << "\n" << e1 << " evaluates to " << v1
-                            << "\n" << e2 << " evaluates to " << v2
-                            << "\n" << e3 << " evaluates to " << v3
-                            << "\n" << e4 << " evaluates to " << v4;
-}
-
-// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
-// Don't use this in your code.
-#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
-  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \
-                on_failure)
-
-// Internal macro for implementing {EXPECT|ASSERT}_PRED4.  Don't use
-// this in your code.
-#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\
-  GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \
-                                             #v1, \
-                                             #v2, \
-                                             #v3, \
-                                             #v4, \
-                                             pred, \
-                                             v1, \
-                                             v2, \
-                                             v3, \
-                                             v4), on_failure)
-
-// 4-ary predicate assertion macros.
-#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
-  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
-#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
-  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
-#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
-  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
-#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
-  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
-
-
-
-// Helper function for implementing {EXPECT|ASSERT}_PRED5.  Don't use
-// this in your code.
-template <typename Pred,
-          typename T1,
-          typename T2,
-          typename T3,
-          typename T4,
-          typename T5>
-AssertionResult AssertPred5Helper(const char* pred_text,
-                                  const char* e1,
-                                  const char* e2,
-                                  const char* e3,
-                                  const char* e4,
-                                  const char* e5,
-                                  Pred pred,
-                                  const T1& v1,
-                                  const T2& v2,
-                                  const T3& v3,
-                                  const T4& v4,
-                                  const T5& v5) {
-  if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
-
-  return AssertionFailure() << pred_text << "("
-                            << e1 << ", "
-                            << e2 << ", "
-                            << e3 << ", "
-                            << e4 << ", "
-                            << e5 << ") evaluates to false, where"
-                            << "\n" << e1 << " evaluates to " << v1
-                            << "\n" << e2 << " evaluates to " << v2
-                            << "\n" << e3 << " evaluates to " << v3
-                            << "\n" << e4 << " evaluates to " << v4
-                            << "\n" << e5 << " evaluates to " << v5;
-}
-
-// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
-// Don't use this in your code.
-#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
-  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
-                on_failure)
-
-// Internal macro for implementing {EXPECT|ASSERT}_PRED5.  Don't use
-// this in your code.
-#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\
-  GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \
-                                             #v1, \
-                                             #v2, \
-                                             #v3, \
-                                             #v4, \
-                                             #v5, \
-                                             pred, \
-                                             v1, \
-                                             v2, \
-                                             v3, \
-                                             v4, \
-                                             v5), on_failure)
-
-// 5-ary predicate assertion macros.
-#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
-  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
-#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
-  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
-#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
-  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
-#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
-  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
-
-
-
-#endif  // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
-
 // Macros for testing equalities and inequalities.
 //
 //    * {ASSERT|EXPECT}_EQ(v1, v2): Tests that v1 == v2
@@ -20880,8 +14657,8 @@
 //
 // Examples:
 //
-//   EXPECT_NE(5, Foo());
-//   EXPECT_EQ(NULL, a_pointer);
+//   EXPECT_NE(Foo(), 5);
+//   EXPECT_EQ(a_pointer, NULL);
 //   ASSERT_LT(i, array_size);
 //   ASSERT_GT(records.size(), 0) << "There is no record left.";
 
@@ -21067,6 +14844,57 @@
 #define EXPECT_NO_FATAL_FAILURE(statement) \
     GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)
 
+// Causes a trace (including the given source file path and line number,
+// and the given message) to be included in every test failure message generated
+// by code in the scope of the lifetime of an instance of this class. The effect
+// is undone with the destruction of the instance.
+//
+// The message argument can be anything streamable to std::ostream.
+//
+// Example:
+//   testing::ScopedTrace trace("file.cc", 123, "message");
+//
+class GTEST_API_ ScopedTrace {
+ public:
+  // The c'tor pushes the given source file location and message onto
+  // a trace stack maintained by Google Test.
+
+  // Template version. Uses Message() to convert the values into strings.
+  // Slow, but flexible.
+  template <typename T>
+  ScopedTrace(const char* file, int line, const T& message) {
+    PushTrace(file, line, (Message() << message).GetString());
+  }
+
+  // Optimize for some known types.
+  ScopedTrace(const char* file, int line, const char* message) {
+    PushTrace(file, line, message ? message : "(null)");
+  }
+
+#if GTEST_HAS_GLOBAL_STRING
+  ScopedTrace(const char* file, int line, const ::string& message) {
+    PushTrace(file, line, message);
+  }
+#endif
+
+  ScopedTrace(const char* file, int line, const std::string& message) {
+    PushTrace(file, line, message);
+  }
+
+  // The d'tor pops the info pushed by the c'tor.
+  //
+  // Note that the d'tor is not virtual in order to be efficient.
+  // Don't inherit from ScopedTrace!
+  ~ScopedTrace();
+
+ private:
+  void PushTrace(const char* file, int line, std::string message);
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace);
+} GTEST_ATTRIBUTE_UNUSED_;  // A ScopedTrace object does its job in its
+                            // c'tor and d'tor.  Therefore it doesn't
+                            // need to be used otherwise.
+
 // Causes a trace (including the source file path, the current line
 // number, and the given message) to be included in every test failure
 // message generated by code in the current scope.  The effect is
@@ -21078,9 +14906,14 @@
 // of the dummy variable name, thus allowing multiple SCOPED_TRACE()s
 // to appear in the same block - as long as they are on different
 // lines.
+//
+// Assuming that each thread maintains its own stack of traces.
+// Therefore, a SCOPED_TRACE() would (correctly) only affect the
+// assertions in its own thread.
 #define SCOPED_TRACE(message) \
-  ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
-    __FILE__, __LINE__, ::testing::Message() << (message))
+  ::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
+    __FILE__, __LINE__, (message))
+
 
 // Compile-time assertion for type equality.
 // StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are
@@ -21120,11 +14953,11 @@
 
 // Defines a test.
 //
-// The first parameter is the name of the test case, and the second
-// parameter is the name of the test within the test case.
+// The first parameter is the name of the test suite, and the second
+// parameter is the name of the test within the test suite.
 //
-// The convention is to end the test case name with "Test".  For
-// example, a test case for the Foo class can be named FooTest.
+// The convention is to end the test suite name with "Test".  For
+// example, a test suite for the Foo class can be named FooTest.
 //
 // Test code should appear between braces after an invocation of
 // this macro.  Example:
@@ -21143,28 +14976,28 @@
 // code.  GetTestTypeId() is guaranteed to always return the same
 // value, as it always calls GetTypeId<>() from the Google Test
 // framework.
-#define GTEST_TEST(test_case_name, test_name)\
-  GTEST_TEST_(test_case_name, test_name, \
-              ::testing::Test, ::testing::internal::GetTestTypeId())
+#define GTEST_TEST(test_suite_name, test_name)             \
+  GTEST_TEST_(test_suite_name, test_name, ::testing::Test, \
+              ::testing::internal::GetTestTypeId())
 
 // Define this macro to 1 to omit the definition of TEST(), which
 // is a generic name and clashes with some other libraries.
 #if !GTEST_DONT_DEFINE_TEST
-# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)
+#define TEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name)
 #endif
 
 // Defines a test that uses a test fixture.
 //
 // The first parameter is the name of the test fixture class, which
-// also doubles as the test case name.  The second parameter is the
-// name of the test within the test case.
+// also doubles as the test suite name.  The second parameter is the
+// name of the test within the test suite.
 //
 // A test fixture class must be declared earlier.  The user should put
-// his test code between braces after using this macro.  Example:
+// the test code between braces after using this macro.  Example:
 //
 //   class FooTest : public testing::Test {
 //    protected:
-//     virtual void SetUp() { b_.AddElement(3); }
+//     void SetUp() override { b_.AddElement(3); }
 //
 //     Foo a_;
 //     Foo b_;
@@ -21175,14 +15008,103 @@
 //   }
 //
 //   TEST_F(FooTest, ReturnsElementCountCorrectly) {
-//     EXPECT_EQ(0, a_.size());
-//     EXPECT_EQ(1, b_.size());
+//     EXPECT_EQ(a_.size(), 0);
+//     EXPECT_EQ(b_.size(), 1);
 //   }
-
+//
+// GOOGLETEST_CM0011 DO NOT DELETE
 #define TEST_F(test_fixture, test_name)\
   GTEST_TEST_(test_fixture, test_name, test_fixture, \
               ::testing::internal::GetTypeId<test_fixture>())
 
+// Returns a path to temporary directory.
+// Tries to determine an appropriate directory for the platform.
+GTEST_API_ std::string TempDir();
+
+#ifdef _MSC_VER
+#  pragma warning(pop)
+#endif
+
+// Dynamically registers a test with the framework.
+//
+// This is an advanced API only to be used when the `TEST` macros are
+// insufficient. The macros should be preferred when possible, as they avoid
+// most of the complexity of calling this function.
+//
+// The `factory` argument is a factory callable (move-constructible) object or
+// function pointer that creates a new instance of the Test object. It
+// handles ownership to the caller. The signature of the callable is
+// `Fixture*()`, where `Fixture` is the test fixture class for the test. All
+// tests registered with the same `test_suite_name` must return the same
+// fixture type. This is checked at runtime.
+//
+// The framework will infer the fixture class from the factory and will call
+// the `SetUpTestSuite` and `TearDownTestSuite` for it.
+//
+// Must be called before `RUN_ALL_TESTS()` is invoked, otherwise behavior is
+// undefined.
+//
+// Use case example:
+//
+// class MyFixture : public ::testing::Test {
+//  public:
+//   // All of these optional, just like in regular macro usage.
+//   static void SetUpTestSuite() { ... }
+//   static void TearDownTestSuite() { ... }
+//   void SetUp() override { ... }
+//   void TearDown() override { ... }
+// };
+//
+// class MyTest : public MyFixture {
+//  public:
+//   explicit MyTest(int data) : data_(data) {}
+//   void TestBody() override { ... }
+//
+//  private:
+//   int data_;
+// };
+//
+// void RegisterMyTests(const std::vector<int>& values) {
+//   for (int v : values) {
+//     ::testing::RegisterTest(
+//         "MyFixture", ("Test" + std::to_string(v)).c_str(), nullptr,
+//         std::to_string(v).c_str(),
+//         __FILE__, __LINE__,
+//         // Important to use the fixture type as the return type here.
+//         [=]() -> MyFixture* { return new MyTest(v); });
+//   }
+// }
+// ...
+// int main(int argc, char** argv) {
+//   std::vector<int> values_to_test = LoadValuesFromConfig();
+//   RegisterMyTests(values_to_test);
+//   ...
+//   return RUN_ALL_TESTS();
+// }
+//
+template <int&... ExplicitParameterBarrier, typename Factory>
+TestInfo* RegisterTest(const char* test_suite_name, const char* test_name,
+                       const char* type_param, const char* value_param,
+                       const char* file, int line, Factory factory) {
+  using TestT = typename std::remove_pointer<decltype(factory())>::type;
+
+  class FactoryImpl : public internal::TestFactoryBase {
+   public:
+    explicit FactoryImpl(Factory f) : factory_(std::move(f)) {}
+    Test* CreateTest() override { return factory_(); }
+
+   private:
+    Factory factory_;
+  };
+
+  return internal::MakeAndRegisterTestInfo(
+      test_suite_name, test_name, type_param, value_param,
+      internal::CodeLocation(file, line), internal::GetTypeId<TestT>(),
+      internal::SuiteApiResolver<TestT>::GetSetUpCaseOrSuite(),
+      internal::SuiteApiResolver<TestT>::GetTearDownCaseOrSuite(),
+      new FactoryImpl{std::move(factory)});
+}
+
 }  // namespace testing
 
 // Use this function in main() to run all tests.  It returns 0 if all
@@ -21199,4 +15121,6 @@
   return ::testing::UnitTest::GetInstance()->Run();
 }
 
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4251
+
 #endif  // GTEST_INCLUDE_GTEST_GTEST_H_
diff --git a/internal/ceres/householder_vector.h b/internal/ceres/householder_vector.h
deleted file mode 100644
index 6d85217..0000000
--- a/internal/ceres/householder_vector.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2015 Google Inc. All rights reserved.
-// http://code.google.com/p/ceres-solver/
-//
-// 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: vitus@google.com (Michael Vitus)
-
-#ifndef CERES_PUBLIC_HOUSEHOLDER_VECTOR_H_
-#define CERES_PUBLIC_HOUSEHOLDER_VECTOR_H_
-
-#include "Eigen/Core"
-#include "glog/logging.h"
-
-namespace ceres {
-namespace internal {
-
-// Algorithm 5.1.1 from 'Matrix Computations' by Golub et al. (Johns Hopkins
-// Studies in Mathematical Sciences) but using the nth element of the input
-// vector as pivot instead of first. This computes the vector v with v(n) = 1
-// and beta such that H = I - beta * v * v^T is orthogonal and
-// H * x = ||x||_2 * e_n.
-template <typename Scalar>
-void ComputeHouseholderVector(const Eigen::Matrix<Scalar, Eigen::Dynamic, 1>& x,
-                              Eigen::Matrix<Scalar, Eigen::Dynamic, 1>* v,
-                              Scalar* beta) {
-  CHECK(beta != nullptr);
-  CHECK(v != nullptr);
-  CHECK_GT(x.rows(), 1);
-  CHECK_EQ(x.rows(), v->rows());
-
-  Scalar sigma = x.head(x.rows() - 1).squaredNorm();
-  *v = x;
-  (*v)(v->rows() - 1) = Scalar(1.0);
-
-  *beta = Scalar(0.0);
-  const Scalar& x_pivot = x(x.rows() - 1);
-
-  if (sigma <= Scalar(std::numeric_limits<double>::epsilon())) {
-    if (x_pivot < Scalar(0.0)) {
-      *beta = Scalar(2.0);
-    }
-    return;
-  }
-
-  const Scalar mu = sqrt(x_pivot * x_pivot + sigma);
-  Scalar v_pivot = Scalar(1.0);
-
-  if (x_pivot <= Scalar(0.0)) {
-    v_pivot = x_pivot - mu;
-  } else {
-    v_pivot = -sigma / (x_pivot + mu);
-  }
-
-  *beta = Scalar(2.0) * v_pivot * v_pivot / (sigma + v_pivot * v_pivot);
-
-  v->head(v->rows() - 1) /= v_pivot;
-}
-
-}  // namespace internal
-}  // namespace ceres
-
-#endif  // CERES_PUBLIC_HOUSEHOLDER_VECTOR_H_
diff --git a/internal/ceres/householder_vector_test.cc b/internal/ceres/householder_vector_test.cc
index fca0360..6f3b172 100644
--- a/internal/ceres/householder_vector_test.cc
+++ b/internal/ceres/householder_vector_test.cc
@@ -28,7 +28,8 @@
 //
 // Author: vitus@google.com (Michael Vitus)
 
-#include "ceres/householder_vector.h"
+#include "ceres/internal/householder_vector.h"
+
 #include "ceres/internal/eigen.h"
 #include "glog/logging.h"
 #include "gtest/gtest.h"
@@ -36,13 +37,17 @@
 namespace ceres {
 namespace internal {
 
-void HouseholderTestHelper(const Vector& x) {
+static void HouseholderTestHelper(const Vector& x) {
   const double kTolerance = 1e-14;
 
   // Check to ensure that H * x = ||x|| * [0 ... 0 1]'.
   Vector v(x.rows());
   double beta;
-  ComputeHouseholderVector(x, &v, &beta);
+
+  // NOTE: The explicit template arguments are needed here because
+  // ComputeHouseholderVector is templated and some versions of MSVC
+  // have trouble deducing the type of v automatically.
+  ComputeHouseholderVector<Vector, double, Eigen::Dynamic>(x, &v, &beta);
   Vector result = x - beta * v * (v.transpose() * x);
 
   Vector expected_result(x.rows());
diff --git a/internal/ceres/implicit_schur_complement.cc b/internal/ceres/implicit_schur_complement.cc
index bf680d1..f2196d4 100644
--- a/internal/ceres/implicit_schur_complement.cc
+++ b/internal/ceres/implicit_schur_complement.cc
@@ -43,13 +43,9 @@
 
 ImplicitSchurComplement::ImplicitSchurComplement(
     const LinearSolver::Options& options)
-    : options_(options),
-      D_(NULL),
-      b_(NULL) {
-}
+    : options_(options), D_(NULL), b_(NULL) {}
 
-ImplicitSchurComplement::~ImplicitSchurComplement() {
-}
+ImplicitSchurComplement::~ImplicitSchurComplement() {}
 
 void ImplicitSchurComplement::Init(const BlockSparseMatrix& A,
                                    const double* D,
@@ -88,7 +84,7 @@
   // the block diagonals and invert them.
   AddDiagonalAndInvert(D_, block_diagonal_EtE_inverse_.get());
   if (options_.preconditioner_type == JACOBI) {
-    AddDiagonalAndInvert((D_ ==  NULL) ? NULL : D_ + A_->num_cols_e(),
+    AddDiagonalAndInvert((D_ == NULL) ? NULL : D_ + A_->num_cols_e(),
                          block_diagonal_FtF_inverse_.get());
   }
 
@@ -125,8 +121,8 @@
   if (D_ != NULL) {
     ConstVectorRef Dref(D_ + A_->num_cols_e(), num_cols());
     VectorRef(y, num_cols()) =
-        (Dref.array().square() *
-         ConstVectorRef(x, num_cols()).array()).matrix();
+        (Dref.array().square() * ConstVectorRef(x, num_cols()).array())
+            .matrix();
   } else {
     VectorRef(y, num_cols()).setZero();
   }
@@ -139,8 +135,7 @@
 // entries D, add them to the diagonal of the matrix and compute the
 // inverse of each diagonal block.
 void ImplicitSchurComplement::AddDiagonalAndInvert(
-    const double* D,
-    BlockSparseMatrix* block_diagonal) {
+    const double* D, BlockSparseMatrix* block_diagonal) {
   const CompressedRowBlockStructure* block_diagonal_structure =
       block_diagonal->block_structure();
   for (int r = 0; r < block_diagonal_structure->rows.size(); ++r) {
@@ -148,17 +143,16 @@
     const int row_block_size = block_diagonal_structure->rows[r].block.size;
     const Cell& cell = block_diagonal_structure->rows[r].cells[0];
     MatrixRef m(block_diagonal->mutable_values() + cell.position,
-                row_block_size, row_block_size);
+                row_block_size,
+                row_block_size);
 
     if (D != NULL) {
       ConstVectorRef d(D + row_block_pos, row_block_size);
       m += d.array().square().matrix().asDiagonal();
     }
 
-    m = m
-        .selfadjointView<Eigen::Upper>()
-        .llt()
-        .solve(Matrix::Identity(row_block_size, row_block_size));
+    m = m.selfadjointView<Eigen::Upper>().llt().solve(
+        Matrix::Identity(row_block_size, row_block_size));
   }
 }
 
@@ -167,7 +161,7 @@
 void ImplicitSchurComplement::BackSubstitute(const double* x, double* y) {
   const int num_cols_e = A_->num_cols_e();
   const int num_cols_f = A_->num_cols_f();
-  const int num_cols =  A_->num_cols();
+  const int num_cols = A_->num_cols();
   const int num_rows = A_->num_rows();
 
   // y1 = F x
@@ -190,7 +184,7 @@
   // computed via back substitution. The second block of variables
   // corresponds to the Schur complement system, so we just copy those
   // values from the solution to the Schur complement.
-  VectorRef(y + num_cols_e, num_cols_f) =  ConstVectorRef(x, num_cols_f);
+  VectorRef(y + num_cols_e, num_cols_f) = ConstVectorRef(x, num_cols_f);
 }
 
 // Compute the RHS of the Schur complement system.
diff --git a/internal/ceres/implicit_schur_complement.h b/internal/ceres/implicit_schur_complement.h
index 1fac72c..e83892a 100644
--- a/internal/ceres/implicit_schur_complement.h
+++ b/internal/ceres/implicit_schur_complement.h
@@ -35,10 +35,12 @@
 #define CERES_INTERNAL_IMPLICIT_SCHUR_COMPLEMENT_H_
 
 #include <memory>
+
+#include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
 #include "ceres/linear_operator.h"
 #include "ceres/linear_solver.h"
 #include "ceres/partitioned_matrix_view.h"
-#include "ceres/internal/eigen.h"
 #include "ceres/types.h"
 
 namespace ceres {
@@ -86,7 +88,7 @@
 // RightMultiply (and the LeftMultiply) methods are not thread safe as
 // they depend on mutable arrays used for the temporaries needed to
 // compute the product y += Sx;
-class ImplicitSchurComplement : public LinearOperator {
+class CERES_EXPORT_INTERNAL ImplicitSchurComplement : public LinearOperator {
  public:
   // num_eliminate_blocks is the number of E blocks in the matrix
   // A.
@@ -113,11 +115,11 @@
   void Init(const BlockSparseMatrix& A, const double* D, const double* b);
 
   // y += Sx, where S is the Schur complement.
-  virtual void RightMultiply(const double* x, double* y) const;
+  void RightMultiply(const double* x, double* y) const final;
 
   // The Schur complement is a symmetric positive definite matrix,
   // thus the left and right multiply operators are the same.
-  virtual void LeftMultiply(const double* x, double* y) const {
+  void LeftMultiply(const double* x, double* y) const final {
     RightMultiply(x, y);
   }
 
@@ -127,9 +129,9 @@
   // complement.
   void BackSubstitute(const double* x, double* y);
 
-  virtual int num_rows() const { return A_->num_cols_f(); }
-  virtual int num_cols() const { return A_->num_cols_f(); }
-  const Vector& rhs()    const { return rhs_;             }
+  int num_rows() const final { return A_->num_cols_f(); }
+  int num_cols() const final { return A_->num_cols_f(); }
+  const Vector& rhs() const { return rhs_; }
 
   const BlockSparseMatrix* block_diagonal_EtE_inverse() const {
     return block_diagonal_EtE_inverse_.get();
diff --git a/internal/ceres/implicit_schur_complement_test.cc b/internal/ceres/implicit_schur_complement_test.cc
index 3beb386..b6d886f 100644
--- a/internal/ceres/implicit_schur_complement_test.cc
+++ b/internal/ceres/implicit_schur_complement_test.cc
@@ -32,6 +32,7 @@
 
 #include <cstddef>
 #include <memory>
+
 #include "Eigen/Dense"
 #include "ceres/block_random_access_dense_matrix.h"
 #include "ceres/block_sparse_matrix.h"
@@ -54,8 +55,8 @@
 const double kEpsilon = 1e-14;
 
 class ImplicitSchurComplementTest : public ::testing::Test {
- protected :
-  virtual void SetUp() {
+ protected:
+  void SetUp() final {
     std::unique_ptr<LinearLeastSquaresProblem> problem(
         CreateLinearLeastSquaresProblemFromId(2));
 
@@ -98,7 +99,8 @@
     lhs->resize(num_schur_rows, num_schur_rows);
     rhs->resize(num_schur_rows);
 
-    eliminator->Eliminate(A_.get(), b_.get(), D, &blhs, rhs->data());
+    eliminator->Eliminate(
+        BlockSparseMatrixData(*A_), b_.get(), D, &blhs, rhs->data());
 
     MatrixRef lhs_ref(blhs.mutable_values(), num_schur_rows, num_schur_rows);
 
@@ -114,8 +116,11 @@
     VectorRef schur_solution(solution->data() + num_cols_ - num_schur_rows,
                              num_schur_rows);
     schur_solution = lhs->selfadjointView<Eigen::Upper>().llt().solve(*rhs);
-    eliminator->BackSubstitute(A_.get(), b_.get(), D,
-                               schur_solution.data(), solution->data());
+    eliminator->BackSubstitute(BlockSparseMatrixData(*A_),
+                               b_.get(),
+                               D,
+                               schur_solution.data(),
+                               solution->data());
   }
 
   AssertionResult TestImplicitSchurComplement(double* D) {
@@ -149,18 +154,18 @@
       // the explicit schur complement.
       if ((y - z).norm() > kEpsilon) {
         return testing::AssertionFailure()
-            << "Explicit and Implicit SchurComplements differ in "
-            << "column " << i << ". explicit: " << y.transpose()
-            << " implicit: " << z.transpose();
+               << "Explicit and Implicit SchurComplements differ in "
+               << "column " << i << ". explicit: " << y.transpose()
+               << " implicit: " << z.transpose();
       }
     }
 
     // Compare the rhs of the reduced linear system
     if ((isc.rhs() - rhs).norm() > kEpsilon) {
       return testing::AssertionFailure()
-            << "Explicit and Implicit SchurComplements differ in "
-            << "rhs. explicit: " << rhs.transpose()
-            << " implicit: " << isc.rhs().transpose();
+             << "Explicit and Implicit SchurComplements differ in "
+             << "rhs. explicit: " << rhs.transpose()
+             << " implicit: " << isc.rhs().transpose();
     }
 
     // Reference solution to the f_block.
@@ -173,9 +178,9 @@
     isc.BackSubstitute(reference_f_sol.data(), sol.data());
     if ((sol - reference_solution).norm() > kEpsilon) {
       return testing::AssertionFailure()
-          << "Explicit and Implicit SchurComplements solutions differ. "
-          << "explicit: " << reference_solution.transpose()
-          << " implicit: " << sol.transpose();
+             << "Explicit and Implicit SchurComplements solutions differ. "
+             << "explicit: " << reference_solution.transpose()
+             << " implicit: " << sol.transpose();
     }
 
     return testing::AssertionSuccess();
diff --git a/internal/ceres/inner_product_computer.cc b/internal/ceres/inner_product_computer.cc
index 2bf8836..ef38b7b 100644
--- a/internal/ceres/inner_product_computer.cc
+++ b/internal/ceres/inner_product_computer.cc
@@ -31,12 +31,12 @@
 #include "ceres/inner_product_computer.h"
 
 #include <algorithm>
+
 #include "ceres/small_blas.h"
 
 namespace ceres {
 namespace internal {
 
-
 // Create the CompressedRowSparseMatrix matrix that will contain the
 // inner product.
 //
@@ -297,7 +297,7 @@
       const Cell& cell1 = m_row.cells[c1];
       const int c1_size = bs->cols[cell1.block_id].size;
       const int row_nnz = rows[bs->cols[cell1.block_id].position + 1] -
-          rows[bs->cols[cell1.block_id].position];
+                          rows[bs->cols[cell1.block_id].position];
 
       int c2_begin, c2_end;
       if (storage_type == CompressedRowSparseMatrix::LOWER_TRIANGULAR) {
@@ -311,6 +311,7 @@
       for (int c2 = c2_begin; c2 < c2_end; ++c2, ++cursor) {
         const Cell& cell2 = m_row.cells[c2];
         const int c2_size = bs->cols[cell2.block_id].size;
+        // clang-format off
         MatrixTransposeMatrixMultiply<Eigen::Dynamic, Eigen::Dynamic,
                                       Eigen::Dynamic, Eigen::Dynamic, 1>(
                                           m_values + cell1.position,
@@ -319,6 +320,7 @@
                                           m_row.block.size, c2_size,
                                           values + result_offsets_[cursor],
                                           0, 0, c1_size, row_nnz);
+        // clang-format on
       }
     }
   }
diff --git a/internal/ceres/inner_product_computer.h b/internal/ceres/inner_product_computer.h
index 73073f8..04ec1d1 100644
--- a/internal/ceres/inner_product_computer.h
+++ b/internal/ceres/inner_product_computer.h
@@ -36,6 +36,7 @@
 
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/compressed_row_sparse_matrix.h"
+#include "ceres/internal/port.h"
 
 namespace ceres {
 namespace internal {
@@ -60,7 +61,7 @@
 // This is not a problem as sparse linear algebra libraries can ignore
 // these entries with ease and the space used is minimal/linear in the
 // size of the matrices.
-class InnerProductComputer {
+class CERES_EXPORT_INTERNAL InnerProductComputer {
  public:
   // Factory
   //
diff --git a/internal/ceres/inner_product_computer_test.cc b/internal/ceres/inner_product_computer_test.cc
index 31cd829..ac564f4 100644
--- a/internal/ceres/inner_product_computer_test.cc
+++ b/internal/ceres/inner_product_computer_test.cc
@@ -32,6 +32,8 @@
 
 #include <memory>
 #include <numeric>
+
+#include "Eigen/SparseCore"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/random.h"
@@ -39,8 +41,6 @@
 #include "glog/logging.h"
 #include "gtest/gtest.h"
 
-#include "Eigen/SparseCore"
-
 namespace ceres {
 namespace internal {
 
@@ -134,7 +134,6 @@
         inner_product_computer.reset(InnerProductComputer::Create(
             *random_matrix, CompressedRowSparseMatrix::UPPER_TRIANGULAR));
         COMPUTE_AND_COMPARE;
-
       }
     }
   }
@@ -215,7 +214,6 @@
             end_row_block,
             CompressedRowSparseMatrix::UPPER_TRIANGULAR));
         COMPUTE_AND_COMPARE;
-
       }
     }
   }
diff --git a/internal/ceres/integer_sequence_algorithm_test.cc b/internal/ceres/integer_sequence_algorithm_test.cc
index a6c85d0..af42a91 100644
--- a/internal/ceres/integer_sequence_algorithm_test.cc
+++ b/internal/ceres/integer_sequence_algorithm_test.cc
@@ -31,39 +31,40 @@
 #include "ceres/internal/integer_sequence_algorithm.h"
 
 #include <type_traits>
+#include <utility>
 
 namespace ceres {
 namespace internal {
 
 // Unit tests for summation of integer sequence.
-static_assert(Sum<integer_sequence<int>>::Value == 0,
+static_assert(Sum<std::integer_sequence<int>>::Value == 0,
               "Unit test of summing up an integer sequence failed.");
-static_assert(Sum<integer_sequence<int, 2>>::Value == 2,
+static_assert(Sum<std::integer_sequence<int, 2>>::Value == 2,
               "Unit test of summing up an integer sequence failed.");
-static_assert(Sum<integer_sequence<int, 2, 3>>::Value == 5,
+static_assert(Sum<std::integer_sequence<int, 2, 3>>::Value == 5,
               "Unit test of summing up an integer sequence failed.");
-static_assert(Sum<integer_sequence<int, 2, 3, 10>>::Value == 15,
+static_assert(Sum<std::integer_sequence<int, 2, 3, 10>>::Value == 15,
               "Unit test of summing up an integer sequence failed.");
-static_assert(Sum<integer_sequence<int, 2, 3, 10, 4>>::Value == 19,
+static_assert(Sum<std::integer_sequence<int, 2, 3, 10, 4>>::Value == 19,
               "Unit test of summing up an integer sequence failed.");
-static_assert(Sum<integer_sequence<int, 2, 3, 10, 4, 1>>::Value == 20,
+static_assert(Sum<std::integer_sequence<int, 2, 3, 10, 4, 1>>::Value == 20,
               "Unit test of summing up an integer sequence failed.");
 
 // Unit tests for exclusive scan of integer sequence.
-static_assert(std::is_same<ExclusiveScan<integer_sequence<int>>,
-                           integer_sequence<int>>::value,
+static_assert(std::is_same<ExclusiveScan<std::integer_sequence<int>>,
+                           std::integer_sequence<int>>::value,
               "Unit test of calculating the exclusive scan of an integer "
               "sequence failed.");
-static_assert(std::is_same<ExclusiveScan<integer_sequence<int, 2>>,
-                           integer_sequence<int, 0>>::value,
+static_assert(std::is_same<ExclusiveScan<std::integer_sequence<int, 2>>,
+                           std::integer_sequence<int, 0>>::value,
               "Unit test of calculating the exclusive scan of an integer "
               "sequence failed.");
-static_assert(std::is_same<ExclusiveScan<integer_sequence<int, 2, 1>>,
-                           integer_sequence<int, 0, 2>>::value,
+static_assert(std::is_same<ExclusiveScan<std::integer_sequence<int, 2, 1>>,
+                           std::integer_sequence<int, 0, 2>>::value,
               "Unit test of calculating the exclusive scan of an integer "
               "sequence failed.");
-static_assert(std::is_same<ExclusiveScan<integer_sequence<int, 2, 1, 10>>,
-                           integer_sequence<int, 0, 2, 3>>::value,
+static_assert(std::is_same<ExclusiveScan<std::integer_sequence<int, 2, 1, 10>>,
+                           std::integer_sequence<int, 0, 2, 3>>::value,
               "Unit test of calculating the exclusive scan of an integer "
               "sequence failed.");
 
diff --git a/internal/ceres/integer_sequence_test.cc b/internal/ceres/integer_sequence_test.cc
deleted file mode 100644
index ab3559a..0000000
--- a/internal/ceres/integer_sequence_test.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2018 Google Inc. All rights reserved.
-// http://ceres-solver.org/
-//
-// 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: jodebo_beck@gmx.de (Johannes Beck)
-
-#include "ceres/internal/integer_sequence.h"
-
-#include <type_traits>
-
-namespace ceres {
-namespace internal {
-
-// Unit test for integer_sequence<...>::value_type
-static_assert(std::is_same<integer_sequence<unsigned int, 0>::value_type,
-                           unsigned int>::value,
-              "Unit test of integer sequence value type failed.");
-
-// Unit tests for make_integer_sequence
-static_assert(
-    std::is_same<make_integer_sequence<int, 0>, integer_sequence<int>>::value,
-    "Unit test of make integer sequence failed.");
-static_assert(std::is_same<make_integer_sequence<int, 1>,
-                           integer_sequence<int, 0>>::value,
-              "Unit test of make integer sequence failed.");
-static_assert(std::is_same<make_integer_sequence<int, 2>,
-                           integer_sequence<int, 0, 1>>::value,
-              "Unit test of make integer sequence failed.");
-static_assert(std::is_same<make_integer_sequence<int, 3>,
-                           integer_sequence<int, 0, 1, 2>>::value,
-              "Unit test of make integer sequence failed.");
-
-}  // namespace internal
-}  // namespace ceres
diff --git a/internal/ceres/invert_psd_matrix.h b/internal/ceres/invert_psd_matrix.h
index 2319fea..ac8808b 100644
--- a/internal/ceres/invert_psd_matrix.h
+++ b/internal/ceres/invert_psd_matrix.h
@@ -31,9 +31,9 @@
 #ifndef CERES_INTERNAL_INVERT_PSD_MATRIX_H_
 #define CERES_INTERNAL_INVERT_PSD_MATRIX_H_
 
+#include "Eigen/Dense"
 #include "ceres/internal/eigen.h"
 #include "glog/logging.h"
-#include "Eigen/Dense"
 
 namespace ceres {
 namespace internal {
@@ -51,28 +51,29 @@
 typename EigenTypes<kSize, kSize>::Matrix InvertPSDMatrix(
     const bool assume_full_rank,
     const typename EigenTypes<kSize, kSize>::Matrix& m) {
+  using MType = typename EigenTypes<kSize, kSize>::Matrix;
   const int size = m.rows();
 
-  // If the matrix can be assumed to be full rank, then just use the
-  // Cholesky factorization to invert it.
+  // If the matrix can be assumed to be full rank, then if it is small
+  // (< 5) and fixed size, use Eigen's optimized inverse()
+  // implementation.
+  //
+  // https://eigen.tuxfamily.org/dox/group__TutorialLinearAlgebra.html#title3
   if (assume_full_rank) {
+    if (kSize > 0 && kSize < 5) {
+      return m.inverse();
+    }
     return m.template selfadjointView<Eigen::Upper>().llt().solve(
-        Matrix::Identity(size, size));
+        MType::Identity(size, size));
   }
 
-  Eigen::JacobiSVD<Matrix> svd(m, Eigen::ComputeThinU | Eigen::ComputeThinV);
-  const double tolerance =
-      std::numeric_limits<double>::epsilon() * size * svd.singularValues()(0);
-
-  return svd.matrixV() *
-         (svd.singularValues().array() > tolerance)
-             .select(svd.singularValues().array().inverse(), 0)
-             .matrix()
-             .asDiagonal() *
-         svd.matrixU().adjoint();
+  // For a thin SVD the number of columns of the matrix need to be dynamic.
+  using SVDMType = typename EigenTypes<kSize, Eigen::Dynamic>::Matrix;
+  Eigen::JacobiSVD<SVDMType> svd(m, Eigen::ComputeThinU | Eigen::ComputeThinV);
+  return svd.solve(MType::Identity(size, size));
 }
 
 }  // namespace internal
 }  // namespace ceres
 
-#endif // CERES_INTERNAL_INVERT_PSD_MATRIX_H_
+#endif  // CERES_INTERNAL_INVERT_PSD_MATRIX_H_
diff --git a/internal/ceres/invert_psd_matrix_benchmark.cc b/internal/ceres/invert_psd_matrix_benchmark.cc
new file mode 100644
index 0000000..02a19f3
--- /dev/null
+++ b/internal/ceres/invert_psd_matrix_benchmark.cc
@@ -0,0 +1,90 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2019 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// 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 materils 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.
+//
+// Authors: sameeragarwal@google.com (Sameer Agarwal)
+
+#include "Eigen/Dense"
+#include "benchmark/benchmark.h"
+#include "ceres/invert_psd_matrix.h"
+
+namespace ceres {
+namespace internal {
+
+template <int kSize>
+void BenchmarkFixedSizedInvertPSDMatrix(benchmark::State& state) {
+  using MatrixType = typename EigenTypes<kSize, kSize>::Matrix;
+  MatrixType input = MatrixType::Random();
+  input += input.transpose() + MatrixType::Identity();
+
+  MatrixType output;
+  constexpr bool kAssumeFullRank = true;
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(
+        output = InvertPSDMatrix<kSize>(kAssumeFullRank, input));
+  }
+}
+
+BENCHMARK_TEMPLATE(BenchmarkFixedSizedInvertPSDMatrix, 1);
+BENCHMARK_TEMPLATE(BenchmarkFixedSizedInvertPSDMatrix, 2);
+BENCHMARK_TEMPLATE(BenchmarkFixedSizedInvertPSDMatrix, 3);
+BENCHMARK_TEMPLATE(BenchmarkFixedSizedInvertPSDMatrix, 4);
+BENCHMARK_TEMPLATE(BenchmarkFixedSizedInvertPSDMatrix, 5);
+BENCHMARK_TEMPLATE(BenchmarkFixedSizedInvertPSDMatrix, 6);
+BENCHMARK_TEMPLATE(BenchmarkFixedSizedInvertPSDMatrix, 7);
+BENCHMARK_TEMPLATE(BenchmarkFixedSizedInvertPSDMatrix, 8);
+BENCHMARK_TEMPLATE(BenchmarkFixedSizedInvertPSDMatrix, 9);
+BENCHMARK_TEMPLATE(BenchmarkFixedSizedInvertPSDMatrix, 10);
+BENCHMARK_TEMPLATE(BenchmarkFixedSizedInvertPSDMatrix, 11);
+BENCHMARK_TEMPLATE(BenchmarkFixedSizedInvertPSDMatrix, 12);
+
+void BenchmarkDynamicallyInvertPSDMatrix(benchmark::State& state) {
+  using MatrixType =
+      typename EigenTypes<Eigen::Dynamic, Eigen::Dynamic>::Matrix;
+  const int size = state.range(0);
+  MatrixType input = MatrixType::Random(size, size);
+  input += input.transpose() + MatrixType::Identity(size, size);
+
+  MatrixType output;
+  constexpr bool kAssumeFullRank = true;
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(
+        output = InvertPSDMatrix<Eigen::Dynamic>(kAssumeFullRank, input));
+  }
+}
+
+BENCHMARK(BenchmarkDynamicallyInvertPSDMatrix)
+    ->Apply([](benchmark::internal::Benchmark* benchmark) {
+      for (int i = 1; i < 13; ++i) {
+        benchmark->Args({i});
+      }
+    });
+
+}  // namespace internal
+}  // namespace ceres
+
+BENCHMARK_MAIN();
diff --git a/internal/ceres/invert_psd_matrix_test.cc b/internal/ceres/invert_psd_matrix_test.cc
index 5da9c11..279eeab 100644
--- a/internal/ceres/invert_psd_matrix_test.cc
+++ b/internal/ceres/invert_psd_matrix_test.cc
@@ -36,13 +36,14 @@
 namespace ceres {
 namespace internal {
 
-static const bool kFullRank = true;
-static const bool kRankDeficient = false;
+static constexpr bool kFullRank = true;
+static constexpr bool kRankDeficient = false;
 
 template <int kSize>
 typename EigenTypes<kSize, kSize>::Matrix RandomPSDMatrixWithEigenValues(
     const typename EigenTypes<kSize>::Vector& eigenvalues) {
-  typename EigenTypes<kSize, kSize>::Matrix m;
+  typename EigenTypes<kSize, kSize>::Matrix m(eigenvalues.rows(),
+                                              eigenvalues.rows());
   m.setRandom();
   Eigen::SelfAdjointEigenSolver<typename EigenTypes<kSize, kSize>::Matrix> es(
       m);
@@ -64,8 +65,9 @@
   eigenvalues = eigenvalues.array().abs().matrix();
   const Matrix m = RandomPSDMatrixWithEigenValues<5>(eigenvalues);
   const Matrix inverse_m = InvertPSDMatrix<5>(kFullRank, m);
-  EXPECT_NEAR((m * inverse_m - Matrix::Identity(5,5)).norm() / 5.0,  0.0,
-              std::numeric_limits<double>::epsilon());
+  EXPECT_NEAR((m * inverse_m - Matrix::Identity(5, 5)).norm() / 5.0,
+              0.0,
+              10 * std::numeric_limits<double>::epsilon());
 }
 
 TEST(InvertPSDMatrix, RankDeficient5x5) {
@@ -82,5 +84,30 @@
               10 * std::numeric_limits<double>::epsilon());
 }
 
+TEST(InvertPSDMatrix, DynamicFullRank5x5) {
+  EigenTypes<Eigen::Dynamic>::Vector eigenvalues(5);
+  eigenvalues.setRandom();
+  eigenvalues = eigenvalues.array().abs().matrix();
+  const Matrix m = RandomPSDMatrixWithEigenValues<Eigen::Dynamic>(eigenvalues);
+  const Matrix inverse_m = InvertPSDMatrix<Eigen::Dynamic>(kFullRank, m);
+  EXPECT_NEAR((m * inverse_m - Matrix::Identity(5, 5)).norm() / 5.0,
+              0.0,
+              10 * std::numeric_limits<double>::epsilon());
+}
+
+TEST(InvertPSDMatrix, DynamicRankDeficient5x5) {
+  EigenTypes<Eigen::Dynamic>::Vector eigenvalues(5);
+  eigenvalues.setRandom();
+  eigenvalues = eigenvalues.array().abs().matrix();
+  eigenvalues(3) = 0.0;
+  const Matrix m = RandomPSDMatrixWithEigenValues<Eigen::Dynamic>(eigenvalues);
+  const Matrix inverse_m = InvertPSDMatrix<Eigen::Dynamic>(kRankDeficient, m);
+  Matrix pseudo_identity = Matrix::Identity(5, 5);
+  pseudo_identity(3, 3) = 0.0;
+  EXPECT_NEAR((m * inverse_m * m - m).norm() / m.norm(),
+              0.0,
+              10 * std::numeric_limits<double>::epsilon());
+}
+
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/is_close.cc b/internal/ceres/is_close.cc
index a91a174..0becf55 100644
--- a/internal/ceres/is_close.cc
+++ b/internal/ceres/is_close.cc
@@ -35,9 +35,11 @@
 
 namespace ceres {
 namespace internal {
-bool IsClose(double x, double y, double relative_precision,
-             double *relative_error,
-             double *absolute_error) {
+bool IsClose(double x,
+             double y,
+             double relative_precision,
+             double* relative_error,
+             double* absolute_error) {
   double local_absolute_error;
   double local_relative_error;
   if (!absolute_error) {
diff --git a/internal/ceres/is_close.h b/internal/ceres/is_close.h
index 7789448..b781a44 100644
--- a/internal/ceres/is_close.h
+++ b/internal/ceres/is_close.h
@@ -33,6 +33,8 @@
 #ifndef CERES_INTERNAL_IS_CLOSE_H_
 #define CERES_INTERNAL_IS_CLOSE_H_
 
+#include "ceres/internal/port.h"
+
 namespace ceres {
 namespace internal {
 // Returns true if x and y have a relative (unsigned) difference less than
@@ -40,11 +42,11 @@
 // difference in relative/absolute_error if non-NULL. If one of the two values
 // is exactly zero, the absolute difference will be compared, and relative_error
 // will be set to the absolute difference.
-bool IsClose(double x,
-             double y,
-             double relative_precision,
-             double *relative_error,
-             double *absolute_error);
+CERES_EXPORT_INTERNAL bool IsClose(double x,
+                                   double y,
+                                   double relative_precision,
+                                   double* relative_error,
+                                   double* absolute_error);
 }  // namespace internal
 }  // namespace ceres
 
diff --git a/internal/ceres/is_close_test.cc b/internal/ceres/is_close_test.cc
index 8f7aaba..12d6236 100644
--- a/internal/ceres/is_close_test.cc
+++ b/internal/ceres/is_close_test.cc
@@ -31,6 +31,7 @@
 // This file contains tests for the IsClose function.
 
 #include "ceres/is_close.h"
+
 #include "gtest/gtest.h"
 
 namespace ceres {
diff --git a/internal/ceres/iterative_refiner.cc b/internal/ceres/iterative_refiner.cc
index fb0e45b..5f0bfdd 100644
--- a/internal/ceres/iterative_refiner.cc
+++ b/internal/ceres/iterative_refiner.cc
@@ -28,9 +28,10 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
-#include <string>
 #include "ceres/iterative_refiner.h"
 
+#include <string>
+
 #include "Eigen/Core"
 #include "ceres/sparse_cholesky.h"
 #include "ceres/sparse_matrix.h"
diff --git a/internal/ceres/iterative_refiner.h b/internal/ceres/iterative_refiner.h
index f969935..08f8d67 100644
--- a/internal/ceres/iterative_refiner.h
+++ b/internal/ceres/iterative_refiner.h
@@ -32,7 +32,10 @@
 #define CERES_INTERNAL_ITERATIVE_REFINER_H_
 
 // This include must come before any #ifndef check on Ceres compile options.
+// clang-format off
 #include "ceres/internal/port.h"
+// clang-format on
+
 #include "ceres/internal/eigen.h"
 
 namespace ceres {
@@ -54,7 +57,7 @@
 // Definite linear systems.
 //
 // The above iterative loop is run until max_num_iterations is reached.
-class IterativeRefiner {
+class CERES_EXPORT_INTERNAL IterativeRefiner {
  public:
   // max_num_iterations is the number of refinement iterations to
   // perform.
diff --git a/internal/ceres/iterative_refiner_test.cc b/internal/ceres/iterative_refiner_test.cc
index 7ca0a5e..49887c6 100644
--- a/internal/ceres/iterative_refiner_test.cc
+++ b/internal/ceres/iterative_refiner_test.cc
@@ -57,27 +57,27 @@
   virtual ~FakeSparseMatrix() {}
 
   // y += Ax
-  virtual void RightMultiply(const double* x, double* y) const {
+  void RightMultiply(const double* x, double* y) const final {
     VectorRef(y, m_.cols()) += m_ * ConstVectorRef(x, m_.cols());
   }
   // y += A'x
-  virtual void LeftMultiply(const double* x, double* y) const {
+  void LeftMultiply(const double* x, double* y) const final {
     // We will assume that this is a symmetric matrix.
     RightMultiply(x, y);
   }
 
-  virtual double* mutable_values() { return m_.data(); }
-  virtual const double* values() const { return m_.data(); }
-  virtual int num_rows() const { return m_.cols(); }
-  virtual int num_cols() const { return m_.cols(); }
-  virtual int num_nonzeros() const { return m_.cols() * m_.cols(); }
+  double* mutable_values() final { return m_.data(); }
+  const double* values() const final { return m_.data(); }
+  int num_rows() const final { return m_.cols(); }
+  int num_cols() const final { return m_.cols(); }
+  int num_nonzeros() const final { return m_.cols() * m_.cols(); }
 
   // The following methods are not needed for tests in this file.
-  virtual void SquaredColumnNorm(double* x) const DO_NOT_CALL;
-  virtual void ScaleColumns(const double* scale) DO_NOT_CALL;
-  virtual void SetZero() DO_NOT_CALL;
-  virtual void ToDenseMatrix(Matrix* dense_matrix) const DO_NOT_CALL;
-  virtual void ToTextFile(FILE* file) const DO_NOT_CALL;
+  void SquaredColumnNorm(double* x) const final DO_NOT_CALL;
+  void ScaleColumns(const double* scale) final DO_NOT_CALL;
+  void SetZero() final DO_NOT_CALL;
+  void ToDenseMatrix(Matrix* dense_matrix) const final DO_NOT_CALL;
+  void ToTextFile(FILE* file) const final DO_NOT_CALL;
 
  private:
   Matrix m_;
@@ -92,9 +92,9 @@
   FakeSparseCholesky(const Matrix& lhs) { lhs_ = lhs.cast<Scalar>(); }
   virtual ~FakeSparseCholesky() {}
 
-  virtual LinearSolverTerminationType Solve(const double* rhs_ptr,
-                                            double* solution_ptr,
-                                            std::string* message) {
+  LinearSolverTerminationType Solve(const double* rhs_ptr,
+                                    double* solution_ptr,
+                                    std::string* message) final {
     const int num_cols = lhs_.cols();
     VectorRef solution(solution_ptr, num_cols);
     ConstVectorRef rhs(rhs_ptr, num_cols);
@@ -103,17 +103,17 @@
   }
 
   // The following methods are not needed for tests in this file.
-  virtual CompressedRowSparseMatrix::StorageType StorageType() const
+  CompressedRowSparseMatrix::StorageType StorageType() const final
       DO_NOT_CALL_WITH_RETURN(CompressedRowSparseMatrix::UPPER_TRIANGULAR);
-  virtual LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
-                                                std::string* message)
+  LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
+                                        std::string* message) final
       DO_NOT_CALL_WITH_RETURN(LINEAR_SOLVER_FAILURE);
 
-  virtual LinearSolverTerminationType FactorAndSolve(
-      CompressedRowSparseMatrix* lhs,
-      const double* rhs,
-      double* solution,
-      std::string* message) DO_NOT_CALL_WITH_RETURN(LINEAR_SOLVER_FAILURE);
+  LinearSolverTerminationType FactorAndSolve(CompressedRowSparseMatrix* lhs,
+                                             const double* rhs,
+                                             double* solution,
+                                             std::string* message) final
+      DO_NOT_CALL_WITH_RETURN(LINEAR_SOLVER_FAILURE);
 
  private:
   Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> lhs_;
diff --git a/internal/ceres/iterative_schur_complement_solver.cc b/internal/ceres/iterative_schur_complement_solver.cc
index 6076c38..143df5e 100644
--- a/internal/ceres/iterative_schur_complement_solver.cc
+++ b/internal/ceres/iterative_schur_complement_solver.cc
@@ -55,8 +55,7 @@
 
 IterativeSchurComplementSolver::IterativeSchurComplementSolver(
     const LinearSolver::Options& options)
-    : options_(options) {
-}
+    : options_(options) {}
 
 IterativeSchurComplementSolver::~IterativeSchurComplementSolver() {}
 
diff --git a/internal/ceres/iterative_schur_complement_solver.h b/internal/ceres/iterative_schur_complement_solver.h
index c058f81..37606b3 100644
--- a/internal/ceres/iterative_schur_complement_solver.h
+++ b/internal/ceres/iterative_schur_complement_solver.h
@@ -32,8 +32,10 @@
 #define CERES_INTERNAL_ITERATIVE_SCHUR_COMPLEMENT_SOLVER_H_
 
 #include <memory>
-#include "ceres/linear_solver.h"
+
 #include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
+#include "ceres/linear_solver.h"
 #include "ceres/types.h"
 
 namespace ceres {
@@ -67,20 +69,21 @@
 // a proof of this fact and others related to this solver please see
 // the section on Domain Decomposition Methods in Saad's book
 // "Iterative Methods for Sparse Linear Systems".
-class IterativeSchurComplementSolver : public BlockSparseMatrixSolver {
+class CERES_EXPORT_INTERNAL IterativeSchurComplementSolver
+    : public BlockSparseMatrixSolver {
  public:
   explicit IterativeSchurComplementSolver(const LinearSolver::Options& options);
-  IterativeSchurComplementSolver(const IterativeSchurComplementSolver&) = delete;
+  IterativeSchurComplementSolver(const IterativeSchurComplementSolver&) =
+      delete;
   void operator=(const IterativeSchurComplementSolver&) = delete;
 
   virtual ~IterativeSchurComplementSolver();
 
  private:
-  virtual LinearSolver::Summary SolveImpl(
-      BlockSparseMatrix* A,
-      const double* b,
-      const LinearSolver::PerSolveOptions& options,
-      double* x);
+  LinearSolver::Summary SolveImpl(BlockSparseMatrix* A,
+                                  const double* b,
+                                  const LinearSolver::PerSolveOptions& options,
+                                  double* x) final;
 
   void CreatePreconditioner(BlockSparseMatrix* A);
 
diff --git a/internal/ceres/iterative_schur_complement_solver_test.cc b/internal/ceres/iterative_schur_complement_solver_test.cc
index 3bf2d92..fdd65c7 100644
--- a/internal/ceres/iterative_schur_complement_solver_test.cc
+++ b/internal/ceres/iterative_schur_complement_solver_test.cc
@@ -36,6 +36,7 @@
 
 #include <cstddef>
 #include <memory>
+
 #include "Eigen/Dense"
 #include "ceres/block_random_access_dense_matrix.h"
 #include "ceres/block_sparse_matrix.h"
@@ -58,7 +59,7 @@
 const double kEpsilon = 1e-14;
 
 class IterativeSchurComplementSolverTest : public ::testing::Test {
- protected :
+ protected:
   void SetUpProblem(int problem_id) {
     std::unique_ptr<LinearLeastSquaresProblem> problem(
         CreateLinearLeastSquaresProblemFromId(problem_id));
@@ -74,9 +75,8 @@
   }
 
   AssertionResult TestSolver(double* D) {
-    TripletSparseMatrix triplet_A(A_->num_rows(),
-                                  A_->num_cols(),
-                                  A_->num_nonzeros());
+    TripletSparseMatrix triplet_A(
+        A_->num_rows(), A_->num_cols(), A_->num_nonzeros());
     A_->ToTripletSparseMatrix(&triplet_A);
 
     DenseSparseMatrix dense_A(triplet_A);
@@ -99,15 +99,15 @@
     IterativeSchurComplementSolver isc(options);
 
     Vector isc_sol(num_cols_);
-    per_solve_options.r_tolerance  = 1e-12;
+    per_solve_options.r_tolerance = 1e-12;
     isc.Solve(A_.get(), b_.get(), per_solve_options, isc_sol.data());
     double diff = (isc_sol - reference_solution).norm();
     if (diff < kEpsilon) {
       return testing::AssertionSuccess();
     } else {
       return testing::AssertionFailure()
-          << "The reference solution differs from the ITERATIVE_SCHUR"
-          << " solution by " << diff << " which is more than " << kEpsilon;
+             << "The reference solution differs from the ITERATIVE_SCHUR"
+             << " solution by " << diff << " which is more than " << kEpsilon;
     }
   }
 
diff --git a/internal/ceres/jet_test.cc b/internal/ceres/jet_test.cc
index 6ae6ef7..36f279d 100644
--- a/internal/ceres/jet_test.cc
+++ b/internal/ceres/jet_test.cc
@@ -44,6 +44,8 @@
 namespace ceres {
 namespace internal {
 
+namespace {
+
 const double kE = 2.71828182845904523536;
 
 typedef Jet<double, 2> J;
@@ -60,61 +62,65 @@
 // On a 32-bit optimized build, the mismatch is about 1.4e-14.
 double const kTolerance = 1e-13;
 
-void ExpectJetsClose(const J &x, const J &y) {
+void ExpectJetsClose(const J& x, const J& y) {
   ExpectClose(x.a, y.a, kTolerance);
   ExpectClose(x.v[0], y.v[0], kTolerance);
   ExpectClose(x.v[1], y.v[1], kTolerance);
 }
 
 const double kStep = 1e-8;
-const double kNumericalTolerance = 1e-6; // Numeric derivation is quite inexact
+const double kNumericalTolerance = 1e-6;  // Numeric derivation is quite inexact
 
 // Differentiate using Jet and confirm results with numerical derivation.
-template<typename Function>
+template <typename Function>
 void NumericalTest(const char* name, const Function& f, const double x) {
   const double exact_dx = f(MakeJet(x, 1.0, 0.0)).v[0];
   const double estimated_dx =
-    (f(J(x + kStep)).a - f(J(x - kStep)).a) / (2.0 * kStep);
-  VL << name << "(" << x << "), exact dx: "
-     << exact_dx << ", estimated dx: " << estimated_dx;
+      (f(J(x + kStep)).a - f(J(x - kStep)).a) / (2.0 * kStep);
+  VL << name << "(" << x << "), exact dx: " << exact_dx
+     << ", estimated dx: " << estimated_dx;
   ExpectClose(exact_dx, estimated_dx, kNumericalTolerance);
 }
 
 // Same as NumericalTest, but given a function taking two arguments.
-template<typename Function>
-void NumericalTest2(const char* name, const Function& f,
-                    const double x, const double y) {
+template <typename Function>
+void NumericalTest2(const char* name,
+                    const Function& f,
+                    const double x,
+                    const double y) {
   const J exact_delta = f(MakeJet(x, 1.0, 0.0), MakeJet(y, 0.0, 1.0));
   const double exact_dx = exact_delta.v[0];
   const double exact_dy = exact_delta.v[1];
 
-  // Sanity check – these should be equivalent:
+  // Sanity check - these should be equivalent:
   EXPECT_EQ(exact_dx, f(MakeJet(x, 1.0, 0.0), MakeJet(y, 0.0, 0.0)).v[0]);
   EXPECT_EQ(exact_dx, f(MakeJet(x, 0.0, 1.0), MakeJet(y, 0.0, 0.0)).v[1]);
   EXPECT_EQ(exact_dy, f(MakeJet(x, 0.0, 0.0), MakeJet(y, 1.0, 0.0)).v[0]);
   EXPECT_EQ(exact_dy, f(MakeJet(x, 0.0, 0.0), MakeJet(y, 0.0, 1.0)).v[1]);
 
   const double estimated_dx =
-    (f(J(x + kStep), J(y)).a - f(J(x - kStep), J(y)).a) / (2.0 * kStep);
+      (f(J(x + kStep), J(y)).a - f(J(x - kStep), J(y)).a) / (2.0 * kStep);
   const double estimated_dy =
-    (f(J(x), J(y + kStep)).a - f(J(x), J(y - kStep)).a) / (2.0 * kStep);
-  VL << name << "(" << x << ", " << y << "), exact dx: "
-     << exact_dx << ", estimated dx: " << estimated_dx;
+      (f(J(x), J(y + kStep)).a - f(J(x), J(y - kStep)).a) / (2.0 * kStep);
+  VL << name << "(" << x << ", " << y << "), exact dx: " << exact_dx
+     << ", estimated dx: " << estimated_dx;
   ExpectClose(exact_dx, estimated_dx, kNumericalTolerance);
-  VL << name << "(" << x << ", " << y << "), exact dy: "
-     << exact_dy << ", estimated dy: " << estimated_dy;
+  VL << name << "(" << x << ", " << y << "), exact dy: " << exact_dy
+     << ", estimated dy: " << estimated_dy;
   ExpectClose(exact_dy, estimated_dy, kNumericalTolerance);
 }
 
+}  // namespace
+
 TEST(Jet, Jet) {
   // Pick arbitrary values for x and y.
   J x = MakeJet(2.3, -2.7, 1e-3);
-  J y = MakeJet(1.7,  0.5, 1e+2);
+  J y = MakeJet(1.7, 0.5, 1e+2);
 
   VL << "x = " << x;
   VL << "y = " << y;
 
-  { // Check that log(exp(x)) == x.
+  {  // Check that log(exp(x)) == x.
     J z = exp(x);
     J w = log(z);
     VL << "z = " << z;
@@ -122,7 +128,7 @@
     ExpectJetsClose(w, x);
   }
 
-  { // Check that (x * y) / x == y.
+  {  // Check that (x * y) / x == y.
     J z = x * y;
     J w = z / x;
     VL << "z = " << z;
@@ -130,7 +136,7 @@
     ExpectJetsClose(w, y);
   }
 
-  { // Check that sqrt(x * x) == x.
+  {  // Check that sqrt(x * x) == x.
     J z = x * x;
     J w = sqrt(z);
     VL << "z = " << z;
@@ -138,7 +144,7 @@
     ExpectJetsClose(w, x);
   }
 
-  { // Check that sqrt(y) * sqrt(y) == y.
+  {  // Check that sqrt(y) * sqrt(y) == y.
     J z = sqrt(y);
     J w = z * z;
     VL << "z = " << z;
@@ -149,23 +155,23 @@
   NumericalTest("sqrt", sqrt<double, 2>, 0.00001);
   NumericalTest("sqrt", sqrt<double, 2>, 1.0);
 
-  { // Check that cos(2*x) = cos(x)^2 - sin(x)^2
+  {  // Check that cos(2*x) = cos(x)^2 - sin(x)^2
     J z = cos(J(2.0) * x);
-    J w = cos(x)*cos(x) - sin(x)*sin(x);
+    J w = cos(x) * cos(x) - sin(x) * sin(x);
     VL << "z = " << z;
     VL << "w = " << w;
     ExpectJetsClose(w, z);
   }
 
-  { // Check that sin(2*x) = 2*cos(x)*sin(x)
+  {  // Check that sin(2*x) = 2*cos(x)*sin(x)
     J z = sin(J(2.0) * x);
-    J w = J(2.0)*cos(x)*sin(x);
+    J w = J(2.0) * cos(x) * sin(x);
     VL << "z = " << z;
     VL << "w = " << w;
     ExpectJetsClose(w, z);
   }
 
-  { // Check that cos(x)*cos(x) + sin(x)*sin(x) = 1
+  {  // Check that cos(x)*cos(x) + sin(x)*sin(x) = 1
     J z = cos(x) * cos(x);
     J w = sin(x) * sin(x);
     VL << "z = " << z;
@@ -173,7 +179,7 @@
     ExpectJetsClose(z + w, J(1.0));
   }
 
-  { // Check that atan2(r*sin(t), r*cos(t)) = t.
+  {  // Check that atan2(r*sin(t), r*cos(t)) = t.
     J t = MakeJet(0.7, -0.3, +1.5);
     J r = MakeJet(2.3, 0.13, -2.4);
     VL << "t = " << t;
@@ -185,7 +191,7 @@
     ExpectJetsClose(u, t);
   }
 
-  { // Check that tan(x) = sin(x) / cos(x).
+  {  // Check that tan(x) = sin(x) / cos(x).
     J z = tan(x);
     J w = sin(x) / cos(x);
     VL << "z = " << z;
@@ -193,7 +199,7 @@
     ExpectJetsClose(z, w);
   }
 
-  { // Check that tan(atan(x)) = x.
+  {  // Check that tan(atan(x)) = x.
     J z = tan(atan(x));
     J w = x;
     VL << "z = " << z;
@@ -201,7 +207,7 @@
     ExpectJetsClose(z, w);
   }
 
-  { // Check that cosh(x)*cosh(x) - sinh(x)*sinh(x) = 1
+  {  // Check that cosh(x)*cosh(x) - sinh(x)*sinh(x) = 1
     J z = cosh(x) * cosh(x);
     J w = sinh(x) * sinh(x);
     VL << "z = " << z;
@@ -209,7 +215,7 @@
     ExpectJetsClose(z - w, J(1.0));
   }
 
-  { // Check that tanh(x + y) = (tanh(x) + tanh(y)) / (1 + tanh(x) tanh(y))
+  {  // Check that tanh(x + y) = (tanh(x) + tanh(y)) / (1 + tanh(x) tanh(y))
     J z = tanh(x + y);
     J w = (tanh(x) + tanh(y)) / (J(1.0) + tanh(x) * tanh(y));
     VL << "z = " << z;
@@ -217,7 +223,7 @@
     ExpectJetsClose(z, w);
   }
 
-  { // Check that pow(x, 1) == x.
+  {  // Check that pow(x, 1) == x.
     VL << "x = " << x;
 
     J u = pow(x, 1.);
@@ -226,7 +232,7 @@
     ExpectJetsClose(x, u);
   }
 
-  { // Check that pow(x, 1) == x.
+  {  // Check that pow(x, 1) == x.
     J y = MakeJet(1, 0.0, 0.0);
     VL << "x = " << x;
     VL << "y = " << y;
@@ -237,7 +243,7 @@
     ExpectJetsClose(x, u);
   }
 
-  { // Check that pow(e, log(x)) == x.
+  {  // Check that pow(e, log(x)) == x.
     J logx = log(x);
 
     VL << "x = " << x;
@@ -249,7 +255,7 @@
     ExpectJetsClose(x, u);
   }
 
-  { // Check that pow(e, log(x)) == x.
+  {  // Check that pow(e, log(x)) == x.
     J logx = log(x);
     J e = MakeJet(kE, 0., 0.);
     VL << "x = " << x;
@@ -261,7 +267,7 @@
     ExpectJetsClose(x, u);
   }
 
-  { // Check that pow(e, log(x)) == x.
+  {  // Check that pow(e, log(x)) == x.
     J logx = log(x);
     J e = MakeJet(kE, 0., 0.);
     VL << "x = " << x;
@@ -273,13 +279,13 @@
     ExpectJetsClose(x, u);
   }
 
-  { // Check that pow(x,y) = exp(y*log(x)).
+  {  // Check that pow(x,y) = exp(y*log(x)).
     J logx = log(x);
     J e = MakeJet(kE, 0., 0.);
     VL << "x = " << x;
     VL << "logx = " << logx;
 
-    J u = pow(e, y*logx);
+    J u = pow(e, y * logx);
     J v = pow(x, y);
     VL << "u = " << u;
     VL << "v = " << v;
@@ -287,7 +293,7 @@
     ExpectJetsClose(v, u);
   }
 
-  { // Check that pow(0, y) == 0 for y > 1, with both arguments Jets.
+  {  // Check that pow(0, y) == 0 for y > 1, with both arguments Jets.
     // This tests special case handling inside pow().
     J a = MakeJet(0, 1, 2);
     J b = MakeJet(2, 3, 4);
@@ -299,7 +305,7 @@
     ExpectJetsClose(c, MakeJet(0, 0, 0));
   }
 
-  { // Check that pow(0, y) == 0 for y == 1, with both arguments Jets.
+  {  // Check that pow(0, y) == 0 for y == 1, with both arguments Jets.
     // This tests special case handling inside pow().
     J a = MakeJet(0, 1, 2);
     J b = MakeJet(1, 3, 4);
@@ -311,10 +317,10 @@
     ExpectJetsClose(c, MakeJet(0, 1, 2));
   }
 
-  { // Check that pow(0, <1) is not finite, with both arguments Jets.
+  {  // Check that pow(0, <1) is not finite, with both arguments Jets.
     for (int i = 1; i < 10; i++) {
       J a = MakeJet(0, 1, 2);
-      J b = MakeJet(i*0.1, 3, 4);       // b = 0.1 ... 0.9
+      J b = MakeJet(i * 0.1, 3, 4);  // b = 0.1 ... 0.9
       VL << "a = " << a;
       VL << "b = " << b;
 
@@ -326,7 +332,7 @@
     }
     for (int i = -10; i < 0; i++) {
       J a = MakeJet(0, 1, 2);
-      J b = MakeJet(i*0.1, 3, 4);       // b = -1,-0.9 ... -0.1
+      J b = MakeJet(i * 0.1, 3, 4);  // b = -1,-0.9 ... -0.1
       VL << "a = " << a;
       VL << "b = " << b;
 
@@ -352,7 +358,7 @@
     }
   }
 
-  { // Check that pow(<0, b) is correct for integer b.
+  {  // Check that pow(<0, b) is correct for integer b.
     // This tests special case handling inside pow().
     J a = MakeJet(-1.5, 3, 4);
 
@@ -371,7 +377,7 @@
     }
   }
 
-  { // Check that pow(<0, b) is correct for noninteger b.
+  {  // Check that pow(<0, b) is correct for noninteger b.
     // This tests special case handling inside pow().
     J a = MakeJet(-1.5, 3, 4);
     J b = MakeJet(-2.5, 0, 5);
@@ -431,7 +437,7 @@
     EXPECT_FALSE(IsFinite(c.v[1]));
   }
 
-  { // Check that 1 + x == x + 1.
+  {  // Check that 1 + x == x + 1.
     J a = x + 1.0;
     J b = 1.0 + x;
     J c = x;
@@ -441,7 +447,7 @@
     ExpectJetsClose(a, c);
   }
 
-  { // Check that 1 - x == -(x - 1).
+  {  // Check that 1 - x == -(x - 1).
     J a = 1.0 - x;
     J b = -(x - 1.0);
     J c = x;
@@ -451,7 +457,7 @@
     ExpectJetsClose(a, -c);
   }
 
-  { // Check that (x/s)*s == (x*s)/s.
+  {  // Check that (x/s)*s == (x*s)/s.
     J a = x / 5.0;
     J b = x * 5.0;
     J c = x;
@@ -464,7 +470,7 @@
     ExpectJetsClose(b, d);
   }
 
-  { // Check that x / y == 1 / (y / x).
+  {  // Check that x / y == 1 / (y / x).
     J a = x / y;
     J b = 1.0 / (y / x);
     VL << "a = " << a;
@@ -473,26 +479,26 @@
     ExpectJetsClose(a, b);
   }
 
-  { // Check that abs(-x * x) == sqrt(x * x).
+  {  // Check that abs(-x * x) == sqrt(x * x).
     ExpectJetsClose(abs(-x), sqrt(x * x));
   }
 
-  { // Check that cos(acos(x)) == x.
+  {  // Check that cos(acos(x)) == x.
     J a = MakeJet(0.1, -2.7, 1e-3);
     ExpectJetsClose(cos(acos(a)), a);
     ExpectJetsClose(acos(cos(a)), a);
 
-    J b = MakeJet(0.6,  0.5, 1e+2);
+    J b = MakeJet(0.6, 0.5, 1e+2);
     ExpectJetsClose(cos(acos(b)), b);
     ExpectJetsClose(acos(cos(b)), b);
   }
 
-  { // Check that sin(asin(x)) == x.
+  {  // Check that sin(asin(x)) == x.
     J a = MakeJet(0.1, -2.7, 1e-3);
     ExpectJetsClose(sin(asin(a)), a);
     ExpectJetsClose(asin(sin(a)), a);
 
-    J b = MakeJet(0.4,  0.5, 1e+2);
+    J b = MakeJet(0.4, 0.5, 1e+2);
     ExpectJetsClose(sin(asin(b)), b);
     ExpectJetsClose(asin(sin(b)), b);
   }
@@ -525,49 +531,71 @@
     ExpectJetsClose(BesselJ0(z) + BesselJn(2, z), (2.0 / z) * BesselJ1(z));
   }
 
-  { // Check that floor of a positive number works.
+  {  // Check that floor of a positive number works.
     J a = MakeJet(0.1, -2.7, 1e-3);
     J b = floor(a);
     J expected = MakeJet(floor(a.a), 0.0, 0.0);
     EXPECT_EQ(expected, b);
   }
 
-  { // Check that floor of a negative number works.
+  {  // Check that floor of a negative number works.
     J a = MakeJet(-1.1, -2.7, 1e-3);
     J b = floor(a);
     J expected = MakeJet(floor(a.a), 0.0, 0.0);
     EXPECT_EQ(expected, b);
   }
 
-  { // Check that floor of a positive number works.
+  {  // Check that floor of a positive number works.
     J a = MakeJet(10.123, -2.7, 1e-3);
     J b = floor(a);
     J expected = MakeJet(floor(a.a), 0.0, 0.0);
     EXPECT_EQ(expected, b);
   }
 
-  { // Check that ceil of a positive number works.
+  {  // Check that ceil of a positive number works.
     J a = MakeJet(0.1, -2.7, 1e-3);
     J b = ceil(a);
     J expected = MakeJet(ceil(a.a), 0.0, 0.0);
     EXPECT_EQ(expected, b);
   }
 
-  { // Check that ceil of a negative number works.
+  {  // Check that ceil of a negative number works.
     J a = MakeJet(-1.1, -2.7, 1e-3);
     J b = ceil(a);
     J expected = MakeJet(ceil(a.a), 0.0, 0.0);
     EXPECT_EQ(expected, b);
   }
 
-  { // Check that ceil of a positive number works.
+  {  // Check that ceil of a positive number works.
     J a = MakeJet(10.123, -2.7, 1e-3);
     J b = ceil(a);
     J expected = MakeJet(ceil(a.a), 0.0, 0.0);
     EXPECT_EQ(expected, b);
   }
 
-  { // Check that cbrt(x * x * x) == x.
+  {  // Check that erf works.
+    J a = MakeJet(10.123, -2.7, 1e-3);
+    J b = erf(a);
+    J expected = MakeJet(erf(a.a), 0.0, 0.0);
+    EXPECT_EQ(expected, b);
+  }
+  NumericalTest("erf", erf<double, 2>, -1.0);
+  NumericalTest("erf", erf<double, 2>, 1e-5);
+  NumericalTest("erf", erf<double, 2>, 0.5);
+  NumericalTest("erf", erf<double, 2>, 100.0);
+
+  {  // Check that erfc works.
+    J a = MakeJet(10.123, -2.7, 1e-3);
+    J b = erfc(a);
+    J expected = MakeJet(erfc(a.a), 0.0, 0.0);
+    EXPECT_EQ(expected, b);
+  }
+  NumericalTest("erfc", erfc<double, 2>, -1.0);
+  NumericalTest("erfc", erfc<double, 2>, 1e-5);
+  NumericalTest("erfc", erfc<double, 2>, 0.5);
+  NumericalTest("erfc", erfc<double, 2>, 100.0);
+
+  {  // Check that cbrt(x * x * x) == x.
     J z = x * x * x;
     J w = cbrt(z);
     VL << "z = " << z;
@@ -575,7 +603,7 @@
     ExpectJetsClose(w, x);
   }
 
-  { // Check that cbrt(y) * cbrt(y) * cbrt(y) == y.
+  {  // Check that cbrt(y) * cbrt(y) * cbrt(y) == y.
     J z = cbrt(y);
     J w = z * z * z;
     VL << "z = " << z;
@@ -583,7 +611,7 @@
     ExpectJetsClose(w, y);
   }
 
-  { // Check that cbrt(x) == pow(x, 1/3).
+  {  // Check that cbrt(x) == pow(x, 1/3).
     J z = cbrt(x);
     J w = pow(x, 1.0 / 3.0);
     VL << "z = " << z;
@@ -595,7 +623,7 @@
   NumericalTest("cbrt", cbrt<double, 2>, 1e-5);
   NumericalTest("cbrt", cbrt<double, 2>, 1.0);
 
-  { // Check that exp2(x) == exp(x * log(2))
+  {  // Check that exp2(x) == exp(x * log(2))
     J z = exp2(x);
     J w = exp(x * log(2.0));
     VL << "z = " << z;
@@ -610,7 +638,7 @@
   NumericalTest("exp2", exp2<double, 2>, 1e-5);
   NumericalTest("exp2", exp2<double, 2>, 1.0);
 
-  { // Check that log2(x) == log(x) / log(2)
+  {  // Check that log2(x) == log(x) / log(2)
     J z = log2(x);
     J w = log(x) / log(2.0);
     VL << "z = " << z;
@@ -621,15 +649,15 @@
   NumericalTest("log2", log2<double, 2>, 1.0);
   NumericalTest("log2", log2<double, 2>, 100.0);
 
-  { // Check that hypot(x, y) == sqrt(x^2 + y^2)
+  {  // Check that hypot(x, y) == sqrt(x^2 + y^2)
     J h = hypot(x, y);
-    J s = sqrt(x*x + y*y);
+    J s = sqrt(x * x + y * y);
     VL << "h = " << h;
     VL << "s = " << s;
     ExpectJetsClose(h, s);
   }
 
-  { // Check that hypot(x, x) == sqrt(2) * abs(x)
+  {  // Check that hypot(x, x) == sqrt(2) * abs(x)
     J h = hypot(x, x);
     J s = sqrt(2.0) * abs(x);
     VL << "h = " << h;
@@ -637,35 +665,35 @@
     ExpectJetsClose(h, s);
   }
 
-  { // Check that the derivative is zero tangentially to the circle:
+  {  // Check that the derivative is zero tangentially to the circle:
     J h = hypot(MakeJet(2.0, 1.0, 1.0), MakeJet(2.0, 1.0, -1.0));
     VL << "h = " << h;
     ExpectJetsClose(h, MakeJet(sqrt(8.0), std::sqrt(2.0), 0.0));
   }
 
-  { // Check that hypot(x, 0) == x
+  {  // Check that hypot(x, 0) == x
     J zero = MakeJet(0.0, 2.0, 3.14);
     J h = hypot(x, zero);
     VL << "h = " << h;
     ExpectJetsClose(x, h);
   }
 
-  { // Check that hypot(0, y) == y
+  {  // Check that hypot(0, y) == y
     J zero = MakeJet(0.0, 2.0, 3.14);
     J h = hypot(zero, y);
     VL << "h = " << h;
     ExpectJetsClose(y, h);
   }
 
-  { // Check that hypot(x, 0) == sqrt(x * x) == x, even when x * x underflows:
-    EXPECT_EQ(DBL_MIN * DBL_MIN, 0.0); // Make sure it underflows
+  {  // Check that hypot(x, 0) == sqrt(x * x) == x, even when x * x underflows:
+    EXPECT_EQ(DBL_MIN * DBL_MIN, 0.0);  // Make sure it underflows
     J huge = MakeJet(DBL_MIN, 2.0, 3.14);
     J h = hypot(huge, J(0.0));
     VL << "h = " << h;
     ExpectJetsClose(h, huge);
   }
 
-  { // Check that hypot(x, 0) == sqrt(x * x) == x, even when x * x overflows:
+  {  // Check that hypot(x, 0) == sqrt(x * x) == x, even when x * x overflows:
     EXPECT_EQ(DBL_MAX * DBL_MAX, std::numeric_limits<double>::infinity());
     J huge = MakeJet(DBL_MAX, 2.0, 3.14);
     J h = hypot(huge, J(0.0));
@@ -673,6 +701,7 @@
     ExpectJetsClose(h, huge);
   }
 
+  // clang-format off
   NumericalTest2("hypot", hypot<double, 2>,  0.0,   1e-5);
   NumericalTest2("hypot", hypot<double, 2>, -1e-5,  0.0);
   NumericalTest2("hypot", hypot<double, 2>,  1e-5,  1e-5);
@@ -682,6 +711,7 @@
   NumericalTest2("hypot", hypot<double, 2>, -1e-3,  1.0);
   NumericalTest2("hypot", hypot<double, 2>, -1e-3, -1.0);
   NumericalTest2("hypot", hypot<double, 2>,  1.0,   2.0);
+  // clang-format on
 
   {
     J z = fmax(x, y);
@@ -694,14 +724,13 @@
     VL << "z = " << z;
     ExpectJetsClose(y, z);
   }
-
 }
 
 TEST(Jet, JetsInEigenMatrices) {
   J x = MakeJet(2.3, -2.7, 1e-3);
-  J y = MakeJet(1.7,  0.5, 1e+2);
+  J y = MakeJet(1.7, 0.5, 1e+2);
   J z = MakeJet(5.3, -4.7, 1e-3);
-  J w = MakeJet(9.7,  1.5, 10.1);
+  J w = MakeJet(9.7, 1.5, 10.1);
 
   Eigen::Matrix<J, 2, 2> M;
   Eigen::Matrix<J, 2, 1> v, r1, r2;
@@ -761,8 +790,6 @@
   EXPECT_FALSE(IsNaN(a));
 }
 
-#if EIGEN_VERSION_AT_LEAST(3, 3, 0)
-
 // The following test ensures that Jets have all the appropriate Eigen
 // related traits so that they can be used as part of matrix
 // decompositions.
@@ -771,11 +798,11 @@
   Eigen::Matrix<J, 3, 1> b, x;
   for (int i = 0; i < 3; ++i) {
     for (int j = 0; j < 3; ++j) {
-      A(i,j) = MakeJet(0.0, i, j * j);
+      A(i, j) = MakeJet(0.0, i, j * j);
     }
     b(i) = MakeJet(i, i, i);
     x(i) = MakeJet(0.0, 0.0, 0.0);
-    A(i,i) = MakeJet(1.0, i, i * i);
+    A(i, i) = MakeJet(1.0, i, i * i);
   }
   x = A.llt().solve(b);
   for (int i = 0; i < 3; ++i) {
@@ -788,11 +815,11 @@
   Eigen::Matrix<J, 3, 1> b, x;
   for (int i = 0; i < 3; ++i) {
     for (int j = 0; j < 3; ++j) {
-      A(i,j) = MakeJet(0.0, i, j * j);
+      A(i, j) = MakeJet(0.0, i, j * j);
     }
     b(i) = MakeJet(i, i, i);
     x(i) = MakeJet(0.0, 0.0, 0.0);
-    A(i,i) = MakeJet(1.0, i, i * i);
+    A(i, i) = MakeJet(1.0, i, i * i);
   }
   x = A.ldlt().solve(b);
   for (int i = 0; i < 3; ++i) {
@@ -805,11 +832,11 @@
   Eigen::Matrix<J, 3, 1> b, x;
   for (int i = 0; i < 3; ++i) {
     for (int j = 0; j < 3; ++j) {
-      A(i,j) = MakeJet(0.0, i, j * j);
+      A(i, j) = MakeJet(0.0, i, j * j);
     }
     b(i) = MakeJet(i, i, i);
     x(i) = MakeJet(0.0, 0.0, 0.0);
-    A(i,i) = MakeJet(1.0, i, i * i);
+    A(i, i) = MakeJet(1.0, i, i * i);
   }
 
   x = A.lu().solve(b);
@@ -821,7 +848,7 @@
 // ScalarBinaryOpTraits is only supported on Eigen versions >= 3.3
 TEST(JetTraitsTest, MatrixScalarUnaryOps) {
   const J x = MakeJet(2.3, -2.7, 1e-3);
-  const J y = MakeJet(1.7,  0.5, 1e+2);
+  const J y = MakeJet(1.7, 0.5, 1e+2);
   Eigen::Matrix<J, 2, 1> a;
   a << x, y;
 
@@ -832,9 +859,9 @@
 
 TEST(JetTraitsTest, MatrixScalarBinaryOps) {
   const J x = MakeJet(2.3, -2.7, 1e-3);
-  const J y = MakeJet(1.7,  0.5, 1e+2);
+  const J y = MakeJet(1.7, 0.5, 1e+2);
   const J z = MakeJet(5.3, -4.7, 1e-3);
-  const J w = MakeJet(9.7,  1.5, 10.1);
+  const J w = MakeJet(9.7, 1.5, 10.1);
 
   Eigen::Matrix<J, 2, 2> M;
   Eigen::Vector2d v;
@@ -862,7 +889,7 @@
 
 TEST(JetTraitsTest, ArrayScalarUnaryOps) {
   const J x = MakeJet(2.3, -2.7, 1e-3);
-  const J y = MakeJet(1.7,  0.5, 1e+2);
+  const J y = MakeJet(1.7, 0.5, 1e+2);
   Eigen::Array<J, 2, 1> a;
   a << x, y;
 
@@ -873,7 +900,7 @@
 
 TEST(JetTraitsTest, ArrayScalarBinaryOps) {
   const J x = MakeJet(2.3, -2.7, 1e-3);
-  const J y = MakeJet(1.7,  0.5, 1e+2);
+  const J y = MakeJet(1.7, 0.5, 1e+2);
 
   Eigen::Array<J, 2, 1> a;
   Eigen::Array2d b;
@@ -896,7 +923,29 @@
   ExpectJetsClose(r3(0), r3(0));
   ExpectJetsClose(r4(1), r4(1));
 }
-#endif   // EIGEN_VERSION_AT_LEAST(3, 3, 0)
+
+TEST(Jet, nested3x) {
+  typedef Jet<J, 2> JJ;
+  typedef Jet<JJ, 2> JJJ;
+
+  JJJ x;
+  x.a = JJ(J(1, 0), 0);
+  x.v[0] = JJ(J(1));
+
+  JJJ y = x * x * x;
+
+  ExpectClose(y.a.a.a, 1, kTolerance);
+  ExpectClose(y.v[0].a.a, 3., kTolerance);
+  ExpectClose(y.v[0].v[0].a, 6., kTolerance);
+  ExpectClose(y.v[0].v[0].v[0], 6., kTolerance);
+
+  JJJ e = exp(x);
+
+  ExpectClose(e.a.a.a, kE, kTolerance);
+  ExpectClose(e.v[0].a.a, kE, kTolerance);
+  ExpectClose(e.v[0].v[0].a, kE, kTolerance);
+  ExpectClose(e.v[0].v[0].v[0], kE, kTolerance);
+}
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/lapack.cc b/internal/ceres/lapack.cc
index 6fc23f4..a159ec7 100644
--- a/internal/ceres/lapack.cc
+++ b/internal/ceres/lapack.cc
@@ -34,12 +34,9 @@
 #include "ceres/linear_solver.h"
 #include "glog/logging.h"
 
+#ifndef CERES_NO_LAPACK
 // C interface to the LAPACK Cholesky factorization and triangular solve.
-extern "C" void dpotrf_(char* uplo,
-                       int* n,
-                       double* a,
-                       int* lda,
-                       int* info);
+extern "C" void dpotrf_(char* uplo, int* n, double* a, int* lda, int* info);
 
 extern "C" void dpotrs_(char* uplo,
                         int* n,
@@ -61,7 +58,7 @@
                        double* work,
                        int* lwork,
                        int* info);
-
+#endif
 
 namespace ceres {
 namespace internal {
@@ -91,10 +88,10 @@
   }
 
   if (info > 0) {
-    *message =
-        StringPrintf(
-            "LAPACK::dpotrf numerical failure. "
-             "The leading minor of order %d is not positive definite.", info);
+    *message = StringPrintf(
+        "LAPACK::dpotrf numerical failure. "
+        "The leading minor of order %d is not positive definite.",
+        info);
     return LINEAR_SOLVER_FAILURE;
   }
 
diff --git a/internal/ceres/lapack.h b/internal/ceres/lapack.h
index 5bb1a22..5c5bf8b 100644
--- a/internal/ceres/lapack.h
+++ b/internal/ceres/lapack.h
@@ -32,6 +32,7 @@
 #define CERES_INTERNAL_LAPACK_H_
 
 #include <string>
+
 #include "ceres/internal/port.h"
 #include "ceres/linear_solver.h"
 
diff --git a/internal/ceres/levenberg_marquardt_strategy.cc b/internal/ceres/levenberg_marquardt_strategy.cc
index 9eec631..cb0e937 100644
--- a/internal/ceres/levenberg_marquardt_strategy.cc
+++ b/internal/ceres/levenberg_marquardt_strategy.cc
@@ -61,8 +61,7 @@
   CHECK_GT(max_radius_, 0.0);
 }
 
-LevenbergMarquardtStrategy::~LevenbergMarquardtStrategy() {
-}
+LevenbergMarquardtStrategy::~LevenbergMarquardtStrategy() {}
 
 TrustRegionStrategy::Summary LevenbergMarquardtStrategy::ComputeStep(
     const TrustRegionStrategy::PerSolveOptions& per_solve_options,
@@ -81,8 +80,8 @@
 
     jacobian->SquaredColumnNorm(diagonal_.data());
     for (int i = 0; i < num_parameters; ++i) {
-      diagonal_[i] = std::min(std::max(diagonal_[i], min_diagonal_),
-                              max_diagonal_);
+      diagonal_[i] =
+          std::min(std::max(diagonal_[i], min_diagonal_), max_diagonal_);
     }
   }
 
@@ -112,7 +111,7 @@
   if (linear_solver_summary.termination_type == LINEAR_SOLVER_FATAL_ERROR) {
     LOG(WARNING) << "Linear solver fatal error: "
                  << linear_solver_summary.message;
-  } else if (linear_solver_summary.termination_type == LINEAR_SOLVER_FAILURE)  {
+  } else if (linear_solver_summary.termination_type == LINEAR_SOLVER_FAILURE) {
     LOG(WARNING) << "Linear solver failure. Failed to compute a step: "
                  << linear_solver_summary.message;
   } else if (!IsArrayValid(num_parameters, step)) {
@@ -138,7 +137,6 @@
     }
   }
 
-
   TrustRegionStrategy::Summary summary;
   summary.residual_norm = linear_solver_summary.residual_norm;
   summary.num_iterations = linear_solver_summary.num_iterations;
@@ -148,8 +146,8 @@
 
 void LevenbergMarquardtStrategy::StepAccepted(double step_quality) {
   CHECK_GT(step_quality, 0.0);
-  radius_ = radius_ / std::max(1.0 / 3.0,
-                               1.0 - pow(2.0 * step_quality - 1.0, 3));
+  radius_ =
+      radius_ / std::max(1.0 / 3.0, 1.0 - pow(2.0 * step_quality - 1.0, 3));
   radius_ = std::min(max_radius_, radius_);
   decrease_factor_ = 2.0;
   reuse_diagonal_ = false;
@@ -161,9 +159,7 @@
   reuse_diagonal_ = true;
 }
 
-double LevenbergMarquardtStrategy::Radius() const {
-  return radius_;
-}
+double LevenbergMarquardtStrategy::Radius() const { return radius_; }
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/levenberg_marquardt_strategy.h b/internal/ceres/levenberg_marquardt_strategy.h
index c87a016..12cd463 100644
--- a/internal/ceres/levenberg_marquardt_strategy.h
+++ b/internal/ceres/levenberg_marquardt_strategy.h
@@ -32,6 +32,7 @@
 #define CERES_INTERNAL_LEVENBERG_MARQUARDT_STRATEGY_H_
 
 #include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
 #include "ceres/trust_region_strategy.h"
 
 namespace ceres {
@@ -42,21 +43,22 @@
 // K. Madsen, H.B. Nielsen and O. Tingleff. Available to download from
 //
 // http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf
-class LevenbergMarquardtStrategy : public TrustRegionStrategy {
+class CERES_EXPORT_INTERNAL LevenbergMarquardtStrategy
+    : public TrustRegionStrategy {
  public:
   explicit LevenbergMarquardtStrategy(
       const TrustRegionStrategy::Options& options);
   virtual ~LevenbergMarquardtStrategy();
 
   // TrustRegionStrategy interface
-  virtual TrustRegionStrategy::Summary ComputeStep(
+  TrustRegionStrategy::Summary ComputeStep(
       const TrustRegionStrategy::PerSolveOptions& per_solve_options,
       SparseMatrix* jacobian,
       const double* residuals,
-      double* step);
-  virtual void StepAccepted(double step_quality);
-  virtual void StepRejected(double step_quality);
-  virtual void StepIsInvalid() {
+      double* step) final;
+  void StepAccepted(double step_quality) final;
+  void StepRejected(double step_quality) final;
+  void StepIsInvalid() final {
     // Treat the current step as a rejected step with no increase in
     // solution quality. Since rejected steps lead to decrease in the
     // size of the trust region, the next time ComputeStep is called,
@@ -64,7 +66,7 @@
     StepRejected(0.0);
   }
 
-  virtual double Radius() const;
+  double Radius() const final;
 
  private:
   LinearSolver* linear_solver_;
@@ -74,11 +76,11 @@
   const double max_diagonal_;
   double decrease_factor_;
   bool reuse_diagonal_;
-  Vector diagonal_;   // diagonal_ =  diag(J'J)
+  Vector diagonal_;  // diagonal_ =  diag(J'J)
   // Scaled copy of diagonal_. Stored here as optimization to prevent
   // allocations in every iteration and reuse when a step fails and
   // ComputeStep is called again.
-  Vector lm_diagonal_;  // lm_diagonal_ = diagonal_ / radius_;
+  Vector lm_diagonal_;  // lm_diagonal_ = sqrt(diagonal_ / radius_);
 };
 
 }  // namespace internal
diff --git a/internal/ceres/levenberg_marquardt_strategy_test.cc b/internal/ceres/levenberg_marquardt_strategy_test.cc
index cfbec71..500f269 100644
--- a/internal/ceres/levenberg_marquardt_strategy_test.cc
+++ b/internal/ceres/levenberg_marquardt_strategy_test.cc
@@ -28,9 +28,11 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
-#include <memory>
-#include "ceres/internal/eigen.h"
 #include "ceres/levenberg_marquardt_strategy.h"
+
+#include <memory>
+
+#include "ceres/internal/eigen.h"
 #include "ceres/linear_solver.h"
 #include "ceres/trust_region_strategy.h"
 #include "glog/logging.h"
@@ -38,11 +40,11 @@
 #include "gmock/mock-log.h"
 #include "gtest/gtest.h"
 
+using testing::_;
 using testing::AllOf;
 using testing::AnyNumber;
 using testing::HasSubstr;
 using testing::ScopedMockLog;
-using testing::_;
 
 namespace ceres {
 namespace internal {
@@ -54,18 +56,16 @@
 class RegularizationCheckingLinearSolver : public DenseSparseMatrixSolver {
  public:
   RegularizationCheckingLinearSolver(const int num_cols, const double* diagonal)
-      : num_cols_(num_cols),
-        diagonal_(diagonal) {
-  }
+      : num_cols_(num_cols), diagonal_(diagonal) {}
 
   virtual ~RegularizationCheckingLinearSolver() {}
 
  private:
-  virtual LinearSolver::Summary SolveImpl(
+  LinearSolver::Summary SolveImpl(
       DenseSparseMatrix* A,
       const double* b,
       const LinearSolver::PerSolveOptions& per_solve_options,
-      double* x) {
+      double* x) final {
     CHECK(per_solve_options.D != nullptr);
     for (int i = 0; i < num_cols_; ++i) {
       EXPECT_NEAR(per_solve_options.D[i], diagonal_[i], kTolerance)
@@ -152,11 +152,11 @@
 #if defined(_MSC_VER)
     // Use GLOG_WARNING to support MSVC if GLOG_NO_ABBREVIATED_SEVERITIES
     // is defined.
-    EXPECT_CALL(log, Log(GLOG_WARNING, _,
-                         HasSubstr("Failed to compute a step")));
+    EXPECT_CALL(log,
+                Log(GLOG_WARNING, _, HasSubstr("Failed to compute a step")));
 #else
-    EXPECT_CALL(log, Log(google::WARNING, _,
-                         HasSubstr("Failed to compute a step")));
+    EXPECT_CALL(log,
+                Log(google::WARNING, _, HasSubstr("Failed to compute a step")));
 #endif
 
     TrustRegionStrategy::Summary summary =
diff --git a/internal/ceres/line_search.cc b/internal/ceres/line_search.cc
index 352c64f..7e871a2 100644
--- a/internal/ceres/line_search.cc
+++ b/internal/ceres/line_search.cc
@@ -57,10 +57,10 @@
 const int kErrorMessageNumericPrecision = 8;
 }  // namespace
 
-ostream& operator<<(ostream &os, const FunctionSample& sample);
+ostream& operator<<(ostream& os, const FunctionSample& sample);
 
 // Convenience stream operator for pushing FunctionSamples into log messages.
-ostream& operator<<(ostream &os, const FunctionSample& sample) {
+ostream& operator<<(ostream& os, const FunctionSample& sample) {
   os << sample.ToDebugString();
   return os;
 }
@@ -73,17 +73,17 @@
                                string* error) {
   LineSearch* line_search = NULL;
   switch (line_search_type) {
-  case ceres::ARMIJO:
-    line_search = new ArmijoLineSearch(options);
-    break;
-  case ceres::WOLFE:
-    line_search = new WolfeLineSearch(options);
-    break;
-  default:
-    *error = string("Invalid line search algorithm type: ") +
-        LineSearchTypeToString(line_search_type) +
-        string(", unable to create line search.");
-    return NULL;
+    case ceres::ARMIJO:
+      line_search = new ArmijoLineSearch(options);
+      break;
+    case ceres::WOLFE:
+      line_search = new WolfeLineSearch(options);
+      break;
+    default:
+      *error = string("Invalid line search algorithm type: ") +
+               LineSearchTypeToString(line_search_type) +
+               string(", unable to create line search.");
+      return NULL;
   }
   return line_search;
 }
@@ -96,8 +96,7 @@
       initial_evaluator_residual_time_in_seconds(0.0),
       initial_evaluator_jacobian_time_in_seconds(0.0) {}
 
-void LineSearchFunction::Init(const Vector& position,
-                              const Vector& direction) {
+void LineSearchFunction::Init(const Vector& position, const Vector& direction) {
   position_ = position;
   direction_ = direction;
 }
@@ -200,9 +199,9 @@
   summary->polynomial_minimization_time_in_seconds = 0.0;
   options().function->ResetTimeStatistics();
   this->DoSearch(step_size_estimate, initial_cost, initial_gradient, summary);
-  options().function->
-      TimeStatistics(&summary->cost_evaluation_time_in_seconds,
-                     &summary->gradient_evaluation_time_in_seconds);
+  options().function->TimeStatistics(
+      &summary->cost_evaluation_time_in_seconds,
+      &summary->gradient_evaluation_time_in_seconds);
 
   summary->total_time_in_seconds = WallTimeInSeconds() - start_time;
 }
@@ -218,8 +217,7 @@
     const double min_step_size,
     const double max_step_size) const {
   if (!current.value_is_valid ||
-      (interpolation_type == BISECTION &&
-       max_step_size <= current.x)) {
+      (interpolation_type == BISECTION && max_step_size <= current.x)) {
     // Either: sample is invalid; or we are using BISECTION and contracting
     // the step size.
     return std::min(std::max(current.x * 0.5, min_step_size), max_step_size);
@@ -274,8 +272,8 @@
   }
 
   double step_size = 0.0, unused_min_value = 0.0;
-  MinimizeInterpolatingPolynomial(samples, min_step_size, max_step_size,
-                                  &step_size, &unused_min_value);
+  MinimizeInterpolatingPolynomial(
+      samples, min_step_size, max_step_size, &step_size, &unused_min_value);
   return step_size;
 }
 
@@ -315,41 +313,43 @@
 
   function->Evaluate(step_size_estimate, kEvaluateGradient, &current);
   while (!current.value_is_valid ||
-         current.value > (initial_cost
-                          + options().sufficient_decrease
-                          * initial_gradient
-                          * current.x)) {
+         current.value > (initial_cost + options().sufficient_decrease *
+                                             initial_gradient * current.x)) {
     // If current.value_is_valid is false, we treat it as if the cost at that
     // point is not large enough to satisfy the sufficient decrease condition.
     ++summary->num_iterations;
     if (summary->num_iterations >= options().max_num_iterations) {
-      summary->error =
-          StringPrintf("Line search failed: Armijo failed to find a point "
-                       "satisfying the sufficient decrease condition within "
-                       "specified max_num_iterations: %d.",
-                       options().max_num_iterations);
-      LOG_IF(WARNING, !options().is_silent) << summary->error;
+      summary->error = StringPrintf(
+          "Line search failed: Armijo failed to find a point "
+          "satisfying the sufficient decrease condition within "
+          "specified max_num_iterations: %d.",
+          options().max_num_iterations);
+      if (!options().is_silent) {
+        LOG(WARNING) << summary->error;
+      }
       return;
     }
 
     const double polynomial_minimization_start_time = WallTimeInSeconds();
-    const double step_size =
-        this->InterpolatingPolynomialMinimizingStepSize(
-            options().interpolation_type,
-            initial_position,
-            previous,
-            current,
-            (options().max_step_contraction * current.x),
-            (options().min_step_contraction * current.x));
+    const double step_size = this->InterpolatingPolynomialMinimizingStepSize(
+        options().interpolation_type,
+        initial_position,
+        previous,
+        current,
+        (options().max_step_contraction * current.x),
+        (options().min_step_contraction * current.x));
     summary->polynomial_minimization_time_in_seconds +=
         (WallTimeInSeconds() - polynomial_minimization_start_time);
 
     if (step_size * descent_direction_max_norm < options().min_step_size) {
-      summary->error =
-          StringPrintf("Line search failed: step_size too small: %.5e "
-                       "with descent_direction_max_norm: %.5e.", step_size,
-                       descent_direction_max_norm);
-      LOG_IF(WARNING, !options().is_silent) << summary->error;
+      summary->error = StringPrintf(
+          "Line search failed: step_size too small: %.5e "
+          "with descent_direction_max_norm: %.5e.",
+          step_size,
+          descent_direction_max_norm);
+      if (!options().is_silent) {
+        LOG(WARNING) << summary->error;
+      }
       return;
     }
 
@@ -435,8 +435,8 @@
   }
 
   VLOG(3) << std::scientific << std::setprecision(kErrorMessageNumericPrecision)
-          << "Starting line search zoom phase with bracket_low: "
-          << bracket_low << ", bracket_high: " << bracket_high
+          << "Starting line search zoom phase with bracket_low: " << bracket_low
+          << ", bracket_high: " << bracket_high
           << ", bracket width: " << fabs(bracket_low.x - bracket_high.x)
           << ", bracket abs delta cost: "
           << fabs(bracket_low.value - bracket_high.value);
@@ -461,11 +461,9 @@
   //          but still has bracket_high.value < initial_position.value.
   //   3. bracket_high is chosen after bracket_low, s.t.
   //      bracket_low.gradient * (bracket_high.x - bracket_low.x) < 0.
-  if (!this->ZoomPhase(initial_position,
-                       bracket_low,
-                       bracket_high,
-                       &solution,
-                       summary) && !solution.value_is_valid) {
+  if (!this->ZoomPhase(
+          initial_position, bracket_low, bracket_high, &solution, summary) &&
+      !solution.value_is_valid) {
     // Failed to find a valid point (given the specified decrease parameters)
     // within the specified bracket.
     return;
@@ -501,20 +499,18 @@
 //
 // Returns false if no step size > minimum step size was found which
 // satisfies at least the Armijo condition.
-bool WolfeLineSearch::BracketingPhase(
-    const FunctionSample& initial_position,
-    const double step_size_estimate,
-    FunctionSample* bracket_low,
-    FunctionSample* bracket_high,
-    bool* do_zoom_search,
-    Summary* summary) const {
+bool WolfeLineSearch::BracketingPhase(const FunctionSample& initial_position,
+                                      const double step_size_estimate,
+                                      FunctionSample* bracket_low,
+                                      FunctionSample* bracket_high,
+                                      bool* do_zoom_search,
+                                      Summary* summary) const {
   LineSearchFunction* function = options().function;
 
   FunctionSample previous = initial_position;
   FunctionSample current;
 
-  const double descent_direction_max_norm =
-      function->DirectionInfinityNorm();
+  const double descent_direction_max_norm = function->DirectionInfinityNorm();
 
   *do_zoom_search = false;
   *bracket_low = initial_position;
@@ -536,10 +532,9 @@
     ++summary->num_iterations;
 
     if (current.value_is_valid &&
-        (current.value > (initial_position.value
-                          + options().sufficient_decrease
-                          * initial_position.gradient
-                          * current.x) ||
+        (current.value > (initial_position.value +
+                          options().sufficient_decrease *
+                              initial_position.gradient * current.x) ||
          (previous.value_is_valid && current.value > previous.value))) {
       // Bracket found: current step size violates Armijo sufficient decrease
       // condition, or has stepped past an inflection point of f() relative to
@@ -556,8 +551,8 @@
     }
 
     if (current.value_is_valid &&
-        fabs(current.gradient) <=
-        -options().sufficient_curvature_decrease * initial_position.gradient) {
+        fabs(current.gradient) <= -options().sufficient_curvature_decrease *
+                                      initial_position.gradient) {
       // Current step size satisfies the strong Wolfe conditions, and is thus a
       // valid termination point, therefore a Zoom not required.
       *bracket_low = current;
@@ -585,23 +580,25 @@
       break;
 
     } else if (current.value_is_valid &&
-               fabs(current.x - previous.x) * descent_direction_max_norm
-               < options().min_step_size) {
+               fabs(current.x - previous.x) * descent_direction_max_norm <
+                   options().min_step_size) {
       // We have shrunk the search bracket to a width less than our tolerance,
       // and still not found either a point satisfying the strong Wolfe
       // conditions, or a valid bracket containing such a point. Stop searching
       // and set bracket_low to the size size amongst all those tested which
       // minimizes f() and satisfies the Armijo condition.
-      LOG_IF(WARNING, !options().is_silent)
-          << "Line search failed: Wolfe bracketing phase shrank "
-          << "bracket width: " << fabs(current.x - previous.x)
-          <<  ", to < tolerance: " << options().min_step_size
-          << ", with descent_direction_max_norm: "
-          << descent_direction_max_norm << ", and failed to find "
-          << "a point satisfying the strong Wolfe conditions or a "
-          << "bracketing containing such a point. Accepting "
-          << "point found satisfying Armijo condition only, to "
-          << "allow continuation.";
+
+      if (!options().is_silent) {
+        LOG(WARNING) << "Line search failed: Wolfe bracketing phase shrank "
+                     << "bracket width: " << fabs(current.x - previous.x)
+                     << ", to < tolerance: " << options().min_step_size
+                     << ", with descent_direction_max_norm: "
+                     << descent_direction_max_norm << ", and failed to find "
+                     << "a point satisfying the strong Wolfe conditions or a "
+                     << "bracketing containing such a point. Accepting "
+                     << "point found satisfying Armijo condition only, to "
+                     << "allow continuation.";
+      }
       *bracket_low = current;
       break;
 
@@ -609,18 +606,22 @@
       // Check num iterations bound here so that we always evaluate the
       // max_num_iterations-th iteration against all conditions, and
       // then perform no additional (unused) evaluations.
-      summary->error =
-          StringPrintf("Line search failed: Wolfe bracketing phase failed to "
-                       "find a point satisfying strong Wolfe conditions, or a "
-                       "bracket containing such a point within specified "
-                       "max_num_iterations: %d", options().max_num_iterations);
-      LOG_IF(WARNING, !options().is_silent) << summary->error;
+      summary->error = StringPrintf(
+          "Line search failed: Wolfe bracketing phase failed to "
+          "find a point satisfying strong Wolfe conditions, or a "
+          "bracket containing such a point within specified "
+          "max_num_iterations: %d",
+          options().max_num_iterations);
+      if (!options().is_silent) {
+        LOG(WARNING) << summary->error;
+      }
       // Ensure that bracket_low is always set to the step size amongst all
       // those tested which minimizes f() and satisfies the Armijo condition
       // when we terminate due to the 'artificial' max_num_iterations condition.
       *bracket_low =
           current.value_is_valid && current.value < bracket_low->value
-          ? current : *bracket_low;
+              ? current
+              : *bracket_low;
       break;
     }
     // Either: f(current) is invalid; or, f(current) is valid, but does not
@@ -632,17 +633,16 @@
     // size.
     //
     // In Nocedal & Wright [1] (p60), the step-size can only increase in the
-    // bracketing phase: step_size_{k+1} \in [step_size_k, step_size_k * factor].
-    // However this does not account for the function returning invalid values
-    // which we support, in which case we need to contract the step size whilst
-    // ensuring that we do not invert the bracket, i.e, we require that:
+    // bracketing phase: step_size_{k+1} \in [step_size_k, step_size_k *
+    // factor]. However this does not account for the function returning invalid
+    // values which we support, in which case we need to contract the step size
+    // whilst ensuring that we do not invert the bracket, i.e, we require that:
     // step_size_{k-1} <= step_size_{k+1} < step_size_k.
     const double min_step_size =
-        current.value_is_valid
-        ? current.x : previous.x;
+        current.value_is_valid ? current.x : previous.x;
     const double max_step_size =
-        current.value_is_valid
-        ? (current.x * options().max_step_expansion) : current.x;
+        current.value_is_valid ? (current.x * options().max_step_expansion)
+                               : current.x;
 
     // We are performing 2-point interpolation only here, but the API of
     // InterpolatingPolynomialMinimizingStepSize() allows for up to
@@ -652,22 +652,24 @@
     DCHECK(!unused_previous.value_is_valid);
     // Contracts step size if f(current) is not valid.
     const double polynomial_minimization_start_time = WallTimeInSeconds();
-    const double step_size =
-        this->InterpolatingPolynomialMinimizingStepSize(
-            options().interpolation_type,
-            previous,
-            unused_previous,
-            current,
-            min_step_size,
-            max_step_size);
+    const double step_size = this->InterpolatingPolynomialMinimizingStepSize(
+        options().interpolation_type,
+        previous,
+        unused_previous,
+        current,
+        min_step_size,
+        max_step_size);
     summary->polynomial_minimization_time_in_seconds +=
         (WallTimeInSeconds() - polynomial_minimization_start_time);
     if (step_size * descent_direction_max_norm < options().min_step_size) {
-      summary->error =
-          StringPrintf("Line search failed: step_size too small: %.5e "
-                       "with descent_direction_max_norm: %.5e", step_size,
-                       descent_direction_max_norm);
-      LOG_IF(WARNING, !options().is_silent) << summary->error;
+      summary->error = StringPrintf(
+          "Line search failed: step_size too small: %.5e "
+          "with descent_direction_max_norm: %.5e",
+          step_size,
+          descent_direction_max_norm);
+      if (!options().is_silent) {
+        LOG(WARNING) << summary->error;
+      }
       return false;
     }
 
@@ -684,8 +686,8 @@
   // Ensure that even if a valid bracket was found, we will only mark a zoom
   // as required if the bracket's width is greater than our minimum tolerance.
   if (*do_zoom_search &&
-      fabs(bracket_high->x - bracket_low->x) * descent_direction_max_norm
-      < options().min_step_size) {
+      fabs(bracket_high->x - bracket_low->x) * descent_direction_max_norm <
+          options().min_step_size) {
     *do_zoom_search = false;
   }
 
@@ -707,8 +709,7 @@
       << std::scientific << std::setprecision(kErrorMessageNumericPrecision)
       << "Ceres bug: f_low input to Wolfe Zoom invalid, please contact "
       << "the developers!, initial_position: " << initial_position
-      << ", bracket_low: " << bracket_low
-      << ", bracket_high: "<< bracket_high;
+      << ", bracket_low: " << bracket_low << ", bracket_high: " << bracket_high;
   // We do not require bracket_high.gradient_is_valid as the gradient condition
   // for a valid bracket is only dependent upon bracket_low.gradient, and
   // in order to minimize jacobian evaluations, bracket_high.gradient may
@@ -725,8 +726,7 @@
       << std::scientific << std::setprecision(kErrorMessageNumericPrecision)
       << "Ceres bug: f_high input to Wolfe Zoom invalid, please "
       << "contact the developers!, initial_position: " << initial_position
-      << ", bracket_low: " << bracket_low
-      << ", bracket_high: "<< bracket_high;
+      << ", bracket_low: " << bracket_low << ", bracket_high: " << bracket_high;
 
   if (bracket_low.gradient * (bracket_high.x - bracket_low.x) >= 0) {
     // The third condition for a valid initial bracket:
@@ -738,18 +738,20 @@
     // returns inconsistent gradient values relative to the function values,
     // we do not CHECK_LT(), but we do stop processing and return an invalid
     // value.
-    summary->error =
-        StringPrintf("Line search failed: Wolfe zoom phase passed a bracket "
-                     "which does not satisfy: bracket_low.gradient * "
-                     "(bracket_high.x - bracket_low.x) < 0 [%.8e !< 0] "
-                     "with initial_position: %s, bracket_low: %s, bracket_high:"
-                     " %s, the most likely cause of which is the cost function "
-                     "returning inconsistent gradient & function values.",
-                     bracket_low.gradient * (bracket_high.x - bracket_low.x),
-                     initial_position.ToDebugString().c_str(),
-                     bracket_low.ToDebugString().c_str(),
-                     bracket_high.ToDebugString().c_str());
-    LOG_IF(WARNING, !options().is_silent) << summary->error;
+    summary->error = StringPrintf(
+        "Line search failed: Wolfe zoom phase passed a bracket "
+        "which does not satisfy: bracket_low.gradient * "
+        "(bracket_high.x - bracket_low.x) < 0 [%.8e !< 0] "
+        "with initial_position: %s, bracket_low: %s, bracket_high:"
+        " %s, the most likely cause of which is the cost function "
+        "returning inconsistent gradient & function values.",
+        bracket_low.gradient * (bracket_high.x - bracket_low.x),
+        initial_position.ToDebugString().c_str(),
+        bracket_low.ToDebugString().c_str(),
+        bracket_high.ToDebugString().c_str());
+    if (!options().is_silent) {
+      LOG(WARNING) << summary->error;
+    }
     solution->value_is_valid = false;
     return false;
   }
@@ -763,25 +765,30 @@
     // not satisfy the Wolfe condition.
     *solution = bracket_low;
     if (summary->num_iterations >= options().max_num_iterations) {
-      summary->error =
-          StringPrintf("Line search failed: Wolfe zoom phase failed to "
-                       "find a point satisfying strong Wolfe conditions "
-                       "within specified max_num_iterations: %d, "
-                       "(num iterations taken for bracketing: %d).",
-                       options().max_num_iterations, num_bracketing_iterations);
-      LOG_IF(WARNING, !options().is_silent) << summary->error;
+      summary->error = StringPrintf(
+          "Line search failed: Wolfe zoom phase failed to "
+          "find a point satisfying strong Wolfe conditions "
+          "within specified max_num_iterations: %d, "
+          "(num iterations taken for bracketing: %d).",
+          options().max_num_iterations,
+          num_bracketing_iterations);
+      if (!options().is_silent) {
+        LOG(WARNING) << summary->error;
+      }
       return false;
     }
-    if (fabs(bracket_high.x - bracket_low.x) * descent_direction_max_norm
-        < options().min_step_size) {
+    if (fabs(bracket_high.x - bracket_low.x) * descent_direction_max_norm <
+        options().min_step_size) {
       // Bracket width has been reduced below tolerance, and no point satisfying
       // the strong Wolfe conditions has been found.
-      summary->error =
-          StringPrintf("Line search failed: Wolfe zoom bracket width: %.5e "
-                       "too small with descent_direction_max_norm: %.5e.",
-                       fabs(bracket_high.x - bracket_low.x),
-                       descent_direction_max_norm);
-      LOG_IF(WARNING, !options().is_silent) << summary->error;
+      summary->error = StringPrintf(
+          "Line search failed: Wolfe zoom bracket width: %.5e "
+          "too small with descent_direction_max_norm: %.5e.",
+          fabs(bracket_high.x - bracket_low.x),
+          descent_direction_max_norm);
+      if (!options().is_silent) {
+        LOG(WARNING) << summary->error;
+      }
       return false;
     }
 
@@ -799,14 +806,13 @@
     const FunctionSample unused_previous;
     DCHECK(!unused_previous.value_is_valid);
     const double polynomial_minimization_start_time = WallTimeInSeconds();
-    const double step_size =
-        this->InterpolatingPolynomialMinimizingStepSize(
-            options().interpolation_type,
-            lower_bound_step,
-            unused_previous,
-            upper_bound_step,
-            lower_bound_step.x,
-            upper_bound_step.x);
+    const double step_size = this->InterpolatingPolynomialMinimizingStepSize(
+        options().interpolation_type,
+        lower_bound_step,
+        unused_previous,
+        upper_bound_step,
+        lower_bound_step.x,
+        upper_bound_step.x);
     summary->polynomial_minimization_time_in_seconds +=
         (WallTimeInSeconds() - polynomial_minimization_start_time);
     // No check on magnitude of step size being too small here as it is
@@ -826,13 +832,17 @@
     const bool kEvaluateGradient = true;
     function->Evaluate(step_size, kEvaluateGradient, solution);
     if (!solution->value_is_valid || !solution->gradient_is_valid) {
-      summary->error =
-          StringPrintf("Line search failed: Wolfe Zoom phase found "
-                       "step_size: %.5e, for which function is invalid, "
-                       "between low_step: %.5e and high_step: %.5e "
-                       "at which function is valid.",
-                       solution->x, bracket_low.x, bracket_high.x);
-      LOG_IF(WARNING, !options().is_silent) << summary->error;
+      summary->error = StringPrintf(
+          "Line search failed: Wolfe Zoom phase found "
+          "step_size: %.5e, for which function is invalid, "
+          "between low_step: %.5e and high_step: %.5e "
+          "at which function is valid.",
+          solution->x,
+          bracket_low.x,
+          bracket_high.x);
+      if (!options().is_silent) {
+        LOG(WARNING) << summary->error;
+      }
       return false;
     }
 
@@ -842,10 +852,9 @@
             << ", bracket_high: " << bracket_high
             << ", minimizing solution: " << *solution;
 
-    if ((solution->value > (initial_position.value
-                            + options().sufficient_decrease
-                            * initial_position.gradient
-                            * solution->x)) ||
+    if ((solution->value > (initial_position.value +
+                            options().sufficient_decrease *
+                                initial_position.gradient * solution->x)) ||
         (solution->value >= bracket_low.value)) {
       // Armijo sufficient decrease not satisfied, or not better
       // than current lowest sample, use as new upper bound.
diff --git a/internal/ceres/line_search.h b/internal/ceres/line_search.h
index a162979..634c971 100644
--- a/internal/ceres/line_search.h
+++ b/internal/ceres/line_search.h
@@ -35,6 +35,7 @@
 
 #include <string>
 #include <vector>
+
 #include "ceres/function_sample.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/port.h"
@@ -262,10 +263,10 @@
   virtual ~ArmijoLineSearch() {}
 
  private:
-  virtual void DoSearch(double step_size_estimate,
-                        double initial_cost,
-                        double initial_gradient,
-                        Summary* summary) const;
+  void DoSearch(double step_size_estimate,
+                double initial_cost,
+                double initial_gradient,
+                Summary* summary) const final;
 };
 
 // Bracketing / Zoom Strong Wolfe condition line search.  This implementation
@@ -295,10 +296,10 @@
                  Summary* summary) const;
 
  private:
-  virtual void DoSearch(double step_size_estimate,
-                        double initial_cost,
-                        double initial_gradient,
-                        Summary* summary) const;
+  void DoSearch(double step_size_estimate,
+                double initial_cost,
+                double initial_gradient,
+                Summary* summary) const final;
 };
 
 }  // namespace internal
diff --git a/internal/ceres/line_search_direction.cc b/internal/ceres/line_search_direction.cc
index 1f9d205..48e6c98 100644
--- a/internal/ceres/line_search_direction.cc
+++ b/internal/ceres/line_search_direction.cc
@@ -29,9 +29,10 @@
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
 #include "ceres/line_search_direction.h"
+
+#include "ceres/internal/eigen.h"
 #include "ceres/line_search_minimizer.h"
 #include "ceres/low_rank_inverse_hessian.h"
-#include "ceres/internal/eigen.h"
 #include "glog/logging.h"
 
 namespace ceres {
@@ -52,9 +53,7 @@
  public:
   NonlinearConjugateGradient(const NonlinearConjugateGradientType type,
                              const double function_tolerance)
-      : type_(type),
-        function_tolerance_(function_tolerance) {
-  }
+      : type_(type), function_tolerance_(function_tolerance) {}
 
   bool NextDirection(const LineSearchMinimizer::State& previous,
                      const LineSearchMinimizer::State& current,
@@ -72,14 +71,14 @@
         break;
       case HESTENES_STIEFEL:
         gradient_change = current.gradient - previous.gradient;
-        beta =  (current.gradient.dot(gradient_change) /
-                 previous.search_direction.dot(gradient_change));
+        beta = (current.gradient.dot(gradient_change) /
+                previous.search_direction.dot(gradient_change));
         break;
       default:
         LOG(FATAL) << "Unknown nonlinear conjugate gradient type: " << type_;
     }
 
-    *search_direction =  -current.gradient + beta * previous.search_direction;
+    *search_direction = -current.gradient + beta * previous.search_direction;
     const double directional_derivative =
         current.gradient.dot(*search_direction);
     if (directional_derivative > -function_tolerance_) {
@@ -144,18 +143,19 @@
 
 class BFGS : public LineSearchDirection {
  public:
-  BFGS(const int num_parameters,
-       const bool use_approximate_eigenvalue_scaling)
+  BFGS(const int num_parameters, const bool use_approximate_eigenvalue_scaling)
       : num_parameters_(num_parameters),
         use_approximate_eigenvalue_scaling_(use_approximate_eigenvalue_scaling),
         initialized_(false),
         is_positive_definite_(true) {
-    LOG_IF(WARNING, num_parameters_ >= 1e3)
-        << "BFGS line search being created with: " << num_parameters_
-        << " parameters, this will allocate a dense approximate inverse Hessian"
-        << " of size: " << num_parameters_ << " x " << num_parameters_
-        << ", consider using the L-BFGS memory-efficient line search direction "
-        << "instead.";
+    if (num_parameters_ >= 1000) {
+      LOG(WARNING) << "BFGS line search being created with: " << num_parameters_
+                   << " parameters, this will allocate a dense approximate "
+                   << "inverse Hessian of size: " << num_parameters_ << " x "
+                   << num_parameters_
+                   << ", consider using the L-BFGS memory-efficient line "
+                   << "search direction instead.";
+    }
     // Construct inverse_hessian_ after logging warning about size s.t. if the
     // allocation crashes us, the log will highlight what the issue likely was.
     inverse_hessian_ = Matrix::Identity(num_parameters, num_parameters);
@@ -212,8 +212,8 @@
     if (delta_x_dot_delta_gradient <=
         kBFGSSecantConditionHessianUpdateTolerance) {
       VLOG(2) << "Skipping BFGS Update, delta_x_dot_delta_gradient too "
-              << "small: " << delta_x_dot_delta_gradient << ", tolerance: "
-              << kBFGSSecantConditionHessianUpdateTolerance
+              << "small: " << delta_x_dot_delta_gradient
+              << ", tolerance: " << kBFGSSecantConditionHessianUpdateTolerance
               << " (Secant condition).";
     } else {
       // Update dense inverse Hessian approximation.
@@ -300,13 +300,13 @@
 
       // Calculate scalar: (1 + \rho_k * y_k' * H_k * y_k)
       const double delta_x_times_delta_x_transpose_scale_factor =
-          (1.0 + (rho_k * delta_gradient.transpose() *
-                  inverse_hessian_.selfadjointView<Eigen::Lower>() *
-                  delta_gradient));
+          (1.0 +
+           (rho_k * delta_gradient.transpose() *
+            inverse_hessian_.selfadjointView<Eigen::Lower>() * delta_gradient));
       // Calculate: B = (1 + \rho_k * y_k' * H_k * y_k) * s_k * s_k'
       Matrix B = Matrix::Zero(num_parameters_, num_parameters_);
-      B.selfadjointView<Eigen::Lower>().
-          rankUpdate(delta_x, delta_x_times_delta_x_transpose_scale_factor);
+      B.selfadjointView<Eigen::Lower>().rankUpdate(
+          delta_x, delta_x_times_delta_x_transpose_scale_factor);
 
       // Finally, update inverse Hessian approximation according to:
       // H_k = H_{k-1} + \rho_k * (B - (A + A')).  Note that (A + A') is
@@ -315,9 +315,8 @@
           rho_k * (B - A - A.transpose());
     }
 
-    *search_direction =
-        inverse_hessian_.selfadjointView<Eigen::Lower>() *
-        (-1.0 * current.gradient);
+    *search_direction = inverse_hessian_.selfadjointView<Eigen::Lower>() *
+                        (-1.0 * current.gradient);
 
     if (search_direction->dot(current.gradient) >= 0.0) {
       LOG(WARNING) << "Numerical failure in BFGS update: inverse Hessian "
@@ -339,16 +338,15 @@
   bool is_positive_definite_;
 };
 
-LineSearchDirection*
-LineSearchDirection::Create(const LineSearchDirection::Options& options) {
+LineSearchDirection* LineSearchDirection::Create(
+    const LineSearchDirection::Options& options) {
   if (options.type == STEEPEST_DESCENT) {
     return new SteepestDescent;
   }
 
   if (options.type == NONLINEAR_CONJUGATE_GRADIENT) {
     return new NonlinearConjugateGradient(
-        options.nonlinear_conjugate_gradient_type,
-        options.function_tolerance);
+        options.nonlinear_conjugate_gradient_type, options.function_tolerance);
   }
 
   if (options.type == ceres::LBFGS) {
diff --git a/internal/ceres/line_search_direction.h b/internal/ceres/line_search_direction.h
index 467578d..2fcf472 100644
--- a/internal/ceres/line_search_direction.h
+++ b/internal/ceres/line_search_direction.h
@@ -47,8 +47,7 @@
           nonlinear_conjugate_gradient_type(FLETCHER_REEVES),
           function_tolerance(1e-12),
           max_lbfgs_rank(20),
-          use_approximate_eigenvalue_bfgs_scaling(true) {
-    }
+          use_approximate_eigenvalue_bfgs_scaling(true) {}
 
     int num_parameters;
     LineSearchDirectionType type;
diff --git a/internal/ceres/line_search_minimizer.cc b/internal/ceres/line_search_minimizer.cc
index ac0a192..ea1c507 100644
--- a/internal/ceres/line_search_minimizer.cc
+++ b/internal/ceres/line_search_minimizer.cc
@@ -41,8 +41,8 @@
 #include "ceres/line_search_minimizer.h"
 
 #include <algorithm>
-#include <cstdlib>
 #include <cmath>
+#include <cstdlib>
 #include <memory>
 #include <string>
 #include <vector>
@@ -88,7 +88,7 @@
                                    Solver::Summary* summary) {
   const bool is_not_silent = !options.is_silent;
   double start_time = WallTimeInSeconds();
-  double iteration_start_time =  start_time;
+  double iteration_start_time = start_time;
 
   CHECK(options.evaluator != nullptr);
   Evaluator* evaluator = options.evaluator.get();
@@ -118,20 +118,25 @@
   // Do initial cost and gradient evaluation.
   if (!evaluator->Evaluate(x.data(),
                            &(current_state.cost),
-                           NULL,
+                           nullptr,
                            current_state.gradient.data(),
-                           NULL)) {
+                           nullptr)) {
     summary->termination_type = FAILURE;
     summary->message = "Initial cost and jacobian evaluation failed.";
-    LOG_IF(WARNING, is_not_silent) << "Terminating: " << summary->message;
+    if (is_not_silent) {
+      LOG(WARNING) << "Terminating: " << summary->message;
+    }
     return;
   }
 
   if (!EvaluateGradientNorms(evaluator, x, &current_state, &summary->message)) {
     summary->termination_type = FAILURE;
-    summary->message = "Initial cost and jacobian evaluation failed. "
-        "More details: " + summary->message;
-    LOG_IF(WARNING, is_not_silent) << "Terminating: " << summary->message;
+    summary->message =
+        "Initial cost and jacobian evaluation failed. More details: " +
+        summary->message;
+    if (is_not_silent) {
+      LOG(WARNING) << "Terminating: " << summary->message;
+    }
     return;
   }
 
@@ -141,20 +146,21 @@
   iteration_summary.gradient_norm = sqrt(current_state.gradient_squared_norm);
   iteration_summary.gradient_max_norm = current_state.gradient_max_norm;
   if (iteration_summary.gradient_max_norm <= options.gradient_tolerance) {
-    summary->message = StringPrintf("Gradient tolerance reached. "
-                                    "Gradient max norm: %e <= %e",
-                                    iteration_summary.gradient_max_norm,
-                                    options.gradient_tolerance);
+    summary->message =
+        StringPrintf("Gradient tolerance reached. Gradient max norm: %e <= %e",
+                     iteration_summary.gradient_max_norm,
+                     options.gradient_tolerance);
     summary->termination_type = CONVERGENCE;
-    VLOG_IF(1, is_not_silent) << "Terminating: " << summary->message;
+    if (is_not_silent) {
+      VLOG(1) << "Terminating: " << summary->message;
+    }
     return;
   }
 
   iteration_summary.iteration_time_in_seconds =
       WallTimeInSeconds() - iteration_start_time;
   iteration_summary.cumulative_time_in_seconds =
-      WallTimeInSeconds() - start_time
-      + summary->preprocessor_time_in_seconds;
+      WallTimeInSeconds() - start_time + summary->preprocessor_time_in_seconds;
   summary->iterations.push_back(iteration_summary);
 
   LineSearchDirection::Options line_search_direction_options;
@@ -189,13 +195,13 @@
   line_search_options.is_silent = options.is_silent;
   line_search_options.function = &line_search_function;
 
-  std::unique_ptr<LineSearch>
-      line_search(LineSearch::Create(options.line_search_type,
-                                     line_search_options,
-                                     &summary->message));
-  if (line_search.get() == NULL) {
+  std::unique_ptr<LineSearch> line_search(LineSearch::Create(
+      options.line_search_type, line_search_options, &summary->message));
+  if (line_search.get() == nullptr) {
     summary->termination_type = FAILURE;
-    LOG_IF(ERROR, is_not_silent) << "Terminating: " << summary->message;
+    if (is_not_silent) {
+      LOG(ERROR) << "Terminating: " << summary->message;
+    }
     return;
   }
 
@@ -211,16 +217,20 @@
     if (iteration_summary.iteration >= options.max_num_iterations) {
       summary->message = "Maximum number of iterations reached.";
       summary->termination_type = NO_CONVERGENCE;
-      VLOG_IF(1, is_not_silent) << "Terminating: " << summary->message;
+      if (is_not_silent) {
+        VLOG(1) << "Terminating: " << summary->message;
+      }
       break;
     }
 
     const double total_solver_time = iteration_start_time - start_time +
-        summary->preprocessor_time_in_seconds;
+                                     summary->preprocessor_time_in_seconds;
     if (total_solver_time >= options.max_solver_time_in_seconds) {
       summary->message = "Maximum solver time reached.";
       summary->termination_type = NO_CONVERGENCE;
-      VLOG_IF(1, is_not_silent) << "Terminating: " << summary->message;
+      if (is_not_silent) {
+        VLOG(1) << "Terminating: " << summary->message;
+      }
       break;
     }
 
@@ -234,23 +244,23 @@
       current_state.search_direction = -current_state.gradient;
     } else {
       line_search_status = line_search_direction->NextDirection(
-          previous_state,
-          current_state,
-          &current_state.search_direction);
+          previous_state, current_state, &current_state.search_direction);
     }
 
     if (!line_search_status &&
         num_line_search_direction_restarts >=
-        options.max_num_line_search_direction_restarts) {
+            options.max_num_line_search_direction_restarts) {
       // Line search direction failed to generate a new direction, and we
       // have already reached our specified maximum number of restarts,
       // terminate optimization.
-      summary->message =
-          StringPrintf("Line search direction failure: specified "
-                       "max_num_line_search_direction_restarts: %d reached.",
-                       options.max_num_line_search_direction_restarts);
+      summary->message = StringPrintf(
+          "Line search direction failure: specified "
+          "max_num_line_search_direction_restarts: %d reached.",
+          options.max_num_line_search_direction_restarts);
       summary->termination_type = FAILURE;
-      LOG_IF(WARNING, is_not_silent) << "Terminating: " << summary->message;
+      if (is_not_silent) {
+        LOG(WARNING) << "Terminating: " << summary->message;
+      }
       break;
     } else if (!line_search_status) {
       // Restart line search direction with gradient descent on first iteration
@@ -259,16 +269,17 @@
                options.max_num_line_search_direction_restarts);
 
       ++num_line_search_direction_restarts;
-      LOG_IF(WARNING, is_not_silent)
-          << "Line search direction algorithm: "
-          << LineSearchDirectionTypeToString(
-              options.line_search_direction_type)
-          << ", failed to produce a valid new direction at "
-          << "iteration: " << iteration_summary.iteration
-          << ". Restarting, number of restarts: "
-          << num_line_search_direction_restarts << " / "
-          << options.max_num_line_search_direction_restarts
-          << " [max].";
+      if (is_not_silent) {
+        LOG(WARNING) << "Line search direction algorithm: "
+                     << LineSearchDirectionTypeToString(
+                            options.line_search_direction_type)
+                     << ", failed to produce a valid new direction at "
+                     << "iteration: " << iteration_summary.iteration
+                     << ". Restarting, number of restarts: "
+                     << num_line_search_direction_restarts << " / "
+                     << options.max_num_line_search_direction_restarts
+                     << " [max].";
+      }
       line_search_direction.reset(
           LineSearchDirection::Create(line_search_direction_options));
       current_state.search_direction = -current_state.gradient;
@@ -286,21 +297,25 @@
     // iteration.
     const double initial_step_size =
         (iteration_summary.iteration == 1 || !line_search_status)
-        ? std::min(1.0, 1.0 / current_state.gradient_max_norm)
-        : std::min(1.0, 2.0 * (current_state.cost - previous_state.cost) /
-                   current_state.directional_derivative);
+            ? std::min(1.0, 1.0 / current_state.gradient_max_norm)
+            : std::min(1.0,
+                       2.0 * (current_state.cost - previous_state.cost) /
+                           current_state.directional_derivative);
     // By definition, we should only ever go forwards along the specified search
     // direction in a line search, most likely cause for this being violated
     // would be a numerical failure in the line search direction calculation.
     if (initial_step_size < 0.0) {
-      summary->message =
-          StringPrintf("Numerical failure in line search, initial_step_size is "
-                       "negative: %.5e, directional_derivative: %.5e, "
-                       "(current_cost - previous_cost): %.5e",
-                       initial_step_size, current_state.directional_derivative,
-                       (current_state.cost - previous_state.cost));
+      summary->message = StringPrintf(
+          "Numerical failure in line search, initial_step_size is "
+          "negative: %.5e, directional_derivative: %.5e, "
+          "(current_cost - previous_cost): %.5e",
+          initial_step_size,
+          current_state.directional_derivative,
+          (current_state.cost - previous_state.cost));
       summary->termination_type = FAILURE;
-      LOG_IF(WARNING, is_not_silent) << "Terminating: " << summary->message;
+      if (is_not_silent) {
+        LOG(WARNING) << "Terminating: " << summary->message;
+      }
       break;
     }
 
@@ -309,14 +324,17 @@
                         current_state.directional_derivative,
                         &line_search_summary);
     if (!line_search_summary.success) {
-      summary->message =
-          StringPrintf("Numerical failure in line search, failed to find "
-                       "a valid step size, (did not run out of iterations) "
-                       "using initial_step_size: %.5e, initial_cost: %.5e, "
-                       "initial_gradient: %.5e.",
-                       initial_step_size, current_state.cost,
-                       current_state.directional_derivative);
-      LOG_IF(WARNING, is_not_silent) << "Terminating: " << summary->message;
+      summary->message = StringPrintf(
+          "Numerical failure in line search, failed to find "
+          "a valid step size, (did not run out of iterations) "
+          "using initial_step_size: %.5e, initial_cost: %.5e, "
+          "initial_gradient: %.5e.",
+          initial_step_size,
+          current_state.cost,
+          current_state.directional_derivative);
+      if (is_not_silent) {
+        LOG(WARNING) << "Terminating: " << summary->message;
+      }
       summary->termination_type = FAILURE;
       break;
     }
@@ -338,12 +356,14 @@
       if (!evaluator->Evaluate(evaluate_options,
                                optimal_point.vector_x.data(),
                                &(current_state.cost),
-                               NULL,
+                               nullptr,
                                current_state.gradient.data(),
-                               NULL)) {
+                               nullptr)) {
         summary->termination_type = FAILURE;
         summary->message = "Cost and jacobian evaluation failed.";
-        LOG_IF(WARNING, is_not_silent) << "Terminating: " << summary->message;
+        if (is_not_silent) {
+          LOG(WARNING) << "Terminating: " << summary->message;
+        }
         return;
       }
     }
@@ -357,7 +377,9 @@
           "Step failed to evaluate. This should not happen as the step was "
           "valid when it was selected by the line search. More details: " +
           summary->message;
-      LOG_IF(WARNING, is_not_silent) << "Terminating: " << summary->message;
+      if (is_not_silent) {
+        LOG(WARNING) << "Terminating: " << summary->message;
+      }
       break;
     }
 
@@ -373,7 +395,7 @@
 
     iteration_summary.step_is_valid = true;
     iteration_summary.step_is_successful = true;
-    iteration_summary.step_size =  current_state.step_size;
+    iteration_summary.step_size = current_state.step_size;
     iteration_summary.line_search_function_evaluations =
         line_search_summary.num_function_evaluations;
     iteration_summary.line_search_gradient_evaluations =
@@ -383,8 +405,8 @@
     iteration_summary.iteration_time_in_seconds =
         WallTimeInSeconds() - iteration_start_time;
     iteration_summary.cumulative_time_in_seconds =
-        WallTimeInSeconds() - start_time
-        + summary->preprocessor_time_in_seconds;
+        WallTimeInSeconds() - start_time +
+        summary->preprocessor_time_in_seconds;
     summary->iterations.push_back(iteration_summary);
 
     // Iterations inside the line search algorithm are considered
@@ -393,7 +415,7 @@
     // minimizer. The number of line search steps is the total number
     // of inner line search iterations (or steps) across the entire
     // minimization.
-    summary->num_line_search_steps +=  line_search_summary.num_iterations;
+    summary->num_line_search_steps += line_search_summary.num_iterations;
     summary->line_search_cost_evaluation_time_in_seconds +=
         line_search_summary.cost_evaluation_time_in_seconds;
     summary->line_search_gradient_evaluation_time_in_seconds +=
@@ -404,41 +426,48 @@
         line_search_summary.total_time_in_seconds;
     ++summary->num_successful_steps;
 
-    const double step_size_tolerance = options.parameter_tolerance *
-                                       (x_norm + options.parameter_tolerance);
+    const double step_size_tolerance =
+        options.parameter_tolerance * (x_norm + options.parameter_tolerance);
     if (iteration_summary.step_norm <= step_size_tolerance) {
-      summary->message =
-          StringPrintf("Parameter tolerance reached. "
-                       "Relative step_norm: %e <= %e.",
-                       (iteration_summary.step_norm /
-                        (x_norm + options.parameter_tolerance)),
-                       options.parameter_tolerance);
+      summary->message = StringPrintf(
+          "Parameter tolerance reached. "
+          "Relative step_norm: %e <= %e.",
+          (iteration_summary.step_norm /
+           (x_norm + options.parameter_tolerance)),
+          options.parameter_tolerance);
       summary->termination_type = CONVERGENCE;
-      VLOG_IF(1, is_not_silent) << "Terminating: " << summary->message;
+      if (is_not_silent) {
+        VLOG(1) << "Terminating: " << summary->message;
+      }
       return;
     }
 
     if (iteration_summary.gradient_max_norm <= options.gradient_tolerance) {
-      summary->message = StringPrintf("Gradient tolerance reached. "
-                                      "Gradient max norm: %e <= %e",
-                                      iteration_summary.gradient_max_norm,
-                                      options.gradient_tolerance);
+      summary->message = StringPrintf(
+          "Gradient tolerance reached. "
+          "Gradient max norm: %e <= %e",
+          iteration_summary.gradient_max_norm,
+          options.gradient_tolerance);
       summary->termination_type = CONVERGENCE;
-      VLOG_IF(1, is_not_silent) << "Terminating: " << summary->message;
+      if (is_not_silent) {
+        VLOG(1) << "Terminating: " << summary->message;
+      }
       break;
     }
 
     const double absolute_function_tolerance =
-        options.function_tolerance * previous_state.cost;
-    if (fabs(iteration_summary.cost_change) <= absolute_function_tolerance) {
-      summary->message =
-          StringPrintf("Function tolerance reached. "
-                       "|cost_change|/cost: %e <= %e",
-                       fabs(iteration_summary.cost_change) /
-                       previous_state.cost,
-                       options.function_tolerance);
+        options.function_tolerance * std::abs(previous_state.cost);
+    if (std::abs(iteration_summary.cost_change) <=
+        absolute_function_tolerance) {
+      summary->message = StringPrintf(
+          "Function tolerance reached. "
+          "|cost_change|/cost: %e <= %e",
+          std::abs(iteration_summary.cost_change) / previous_state.cost,
+          options.function_tolerance);
       summary->termination_type = CONVERGENCE;
-      VLOG_IF(1, is_not_silent) << "Terminating: " << summary->message;
+      if (is_not_silent) {
+        VLOG(1) << "Terminating: " << summary->message;
+      }
       break;
     }
   }
diff --git a/internal/ceres/line_search_minimizer.h b/internal/ceres/line_search_minimizer.h
index 54b7202..79e8dc9 100644
--- a/internal/ceres/line_search_minimizer.h
+++ b/internal/ceres/line_search_minimizer.h
@@ -31,10 +31,10 @@
 #ifndef CERES_INTERNAL_LINE_SEARCH_MINIMIZER_H_
 #define CERES_INTERNAL_LINE_SEARCH_MINIMIZER_H_
 
+#include "ceres/internal/eigen.h"
 #include "ceres/minimizer.h"
 #include "ceres/solver.h"
 #include "ceres/types.h"
-#include "ceres/internal/eigen.h"
 #include "glog/logging.h"
 
 namespace ceres {
@@ -46,15 +46,13 @@
 class LineSearchMinimizer : public Minimizer {
  public:
   struct State {
-    State(int num_parameters,
-          int num_effective_parameters)
+    State(int num_parameters, int num_effective_parameters)
         : cost(0.0),
           gradient(num_effective_parameters),
           gradient_squared_norm(0.0),
           search_direction(num_effective_parameters),
           directional_derivative(0.0),
-          step_size(0.0) {
-    }
+          step_size(0.0) {}
 
     double cost;
     Vector gradient;
@@ -66,9 +64,9 @@
   };
 
   ~LineSearchMinimizer() {}
-  virtual void Minimize(const Minimizer::Options& options,
-                        double* parameters,
-                        Solver::Summary* summary);
+  void Minimize(const Minimizer::Options& options,
+                double* parameters,
+                Solver::Summary* summary) final;
 };
 
 }  // namespace internal
diff --git a/internal/ceres/line_search_minimizer_test.cc b/internal/ceres/line_search_minimizer_test.cc
index aa83769..2ef27b9 100644
--- a/internal/ceres/line_search_minimizer_test.cc
+++ b/internal/ceres/line_search_minimizer_test.cc
@@ -40,10 +40,9 @@
 
 class QuadraticFirstOrderFunction : public ceres::FirstOrderFunction {
  public:
-  virtual bool Evaluate(const double* parameters,
-                        double* cost,
-                        double* gradient) const {
-
+  bool Evaluate(const double* parameters,
+                double* cost,
+                double* gradient) const final {
     cost[0] = parameters[0] * parameters[0];
     if (gradient != NULL) {
       gradient[0] = 2.0 * parameters[0];
@@ -51,7 +50,7 @@
     return true;
   }
 
-  virtual int NumParameters() const { return 1; }
+  int NumParameters() const final { return 1; }
 };
 
 TEST(LineSearchMinimizerTest, FinalCostIsZero) {
diff --git a/internal/ceres/line_search_preprocessor.cc b/internal/ceres/line_search_preprocessor.cc
index 17226ad..6a69425 100644
--- a/internal/ceres/line_search_preprocessor.cc
+++ b/internal/ceres/line_search_preprocessor.cc
@@ -32,6 +32,7 @@
 
 #include <numeric>
 #include <string>
+
 #include "ceres/casts.h"
 #include "ceres/context_impl.h"
 #include "ceres/evaluator.h"
@@ -60,17 +61,16 @@
   pp->evaluator_options.num_eliminate_blocks = 0;
   pp->evaluator_options.num_threads = pp->options.num_threads;
   pp->evaluator_options.context = pp->problem->context();
-  pp->evaluator_options.evaluation_callback = pp->options.evaluation_callback;
-  pp->evaluator.reset(Evaluator::Create(pp->evaluator_options,
-                                        pp->reduced_program.get(),
-                                        &pp->error));
+  pp->evaluator_options.evaluation_callback =
+      pp->reduced_program->mutable_evaluation_callback();
+  pp->evaluator.reset(Evaluator::Create(
+      pp->evaluator_options, pp->reduced_program.get(), &pp->error));
   return (pp->evaluator.get() != NULL);
 }
 
 }  // namespace
 
-LineSearchPreprocessor::~LineSearchPreprocessor() {
-}
+LineSearchPreprocessor::~LineSearchPreprocessor() {}
 
 bool LineSearchPreprocessor::Preprocess(const Solver::Options& options,
                                         ProblemImpl* problem,
@@ -85,10 +85,8 @@
     return false;
   }
 
-  pp->reduced_program.reset(
-      program->CreateReducedProgram(&pp->removed_parameter_blocks,
-                                    &pp->fixed_cost,
-                                    &pp->error));
+  pp->reduced_program.reset(program->CreateReducedProgram(
+      &pp->removed_parameter_blocks, &pp->fixed_cost, &pp->error));
 
   if (pp->reduced_program.get() == NULL) {
     return false;
diff --git a/internal/ceres/line_search_preprocessor.h b/internal/ceres/line_search_preprocessor.h
index 132d83a..bd426c7 100644
--- a/internal/ceres/line_search_preprocessor.h
+++ b/internal/ceres/line_search_preprocessor.h
@@ -31,17 +31,18 @@
 #ifndef CERES_INTERNAL_LINE_SEARCH_PREPROCESSOR_H_
 #define CERES_INTERNAL_LINE_SEARCH_PREPROCESSOR_H_
 
+#include "ceres/internal/port.h"
 #include "ceres/preprocessor.h"
 
 namespace ceres {
 namespace internal {
 
-class LineSearchPreprocessor : public Preprocessor {
+class CERES_EXPORT_INTERNAL LineSearchPreprocessor : public Preprocessor {
  public:
   virtual ~LineSearchPreprocessor();
-  virtual bool Preprocess(const Solver::Options& options,
-                          ProblemImpl* problem,
-                          PreprocessedProblem* preprocessed_problem);
+  bool Preprocess(const Solver::Options& options,
+                  ProblemImpl* problem,
+                  PreprocessedProblem* preprocessed_problem) final;
 };
 
 }  // namespace internal
diff --git a/internal/ceres/line_search_preprocessor_test.cc b/internal/ceres/line_search_preprocessor_test.cc
index 301509c..68860c5 100644
--- a/internal/ceres/line_search_preprocessor_test.cc
+++ b/internal/ceres/line_search_preprocessor_test.cc
@@ -28,9 +28,10 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/line_search_preprocessor.h"
+
 #include <map>
 
-#include "ceres/line_search_preprocessor.h"
 #include "ceres/problem_impl.h"
 #include "ceres/sized_cost_function.h"
 #include "ceres/solver.h"
diff --git a/internal/ceres/linear_least_squares_problems.cc b/internal/ceres/linear_least_squares_problems.cc
index 7c523d3..299051c 100644
--- a/internal/ceres/linear_least_squares_problems.cc
+++ b/internal/ceres/linear_least_squares_problems.cc
@@ -101,7 +101,7 @@
 
   int counter = 0;
   for (int i = 0; i < 3; ++i) {
-    for (int j = 0; j< 2; ++j) {
+    for (int j = 0; j < 2; ++j) {
       Ai[counter] = i;
       Aj[counter] = j;
       ++counter;
@@ -132,7 +132,6 @@
   return problem;
 }
 
-
 /*
       A = [1 0  | 2 0 0
            3 0  | 0 4 0
@@ -187,9 +186,8 @@
   int num_cols = 5;
 
   LinearLeastSquaresProblem* problem = new LinearLeastSquaresProblem;
-  TripletSparseMatrix* A = new TripletSparseMatrix(num_rows,
-                                                   num_cols,
-                                                   num_rows * num_cols);
+  TripletSparseMatrix* A =
+      new TripletSparseMatrix(num_rows, num_cols, num_rows * num_cols);
   problem->b.reset(new double[num_rows]);
   problem->D.reset(new double[num_cols]);
   problem->num_eliminate_blocks = 2;
@@ -404,7 +402,6 @@
   return problem;
 }
 
-
 /*
       A = [1 0
            3 0
@@ -620,8 +617,7 @@
   LOG(INFO) << "A^T: \n" << AA.transpose();
 
   if (D != NULL) {
-    LOG(INFO) << "A's appended diagonal:\n"
-              << ConstVectorRef(D, A->num_cols());
+    LOG(INFO) << "A's appended diagonal:\n" << ConstVectorRef(D, A->num_cols());
   }
 
   if (b != NULL) {
@@ -659,10 +655,8 @@
   string matlab_script;
   StringAppendF(&matlab_script,
                 "function lsqp = load_trust_region_problem()\n");
-  StringAppendF(&matlab_script,
-                "lsqp.num_rows = %d;\n", A->num_rows());
-  StringAppendF(&matlab_script,
-                "lsqp.num_cols = %d;\n", A->num_cols());
+  StringAppendF(&matlab_script, "lsqp.num_rows = %d;\n", A->num_rows());
+  StringAppendF(&matlab_script, "lsqp.num_cols = %d;\n", A->num_cols());
 
   {
     string filename = filename_base + "_A.txt";
@@ -670,8 +664,8 @@
     CHECK(fptr != nullptr);
     A->ToTextFile(fptr);
     fclose(fptr);
-    StringAppendF(&matlab_script,
-                  "tmp = load('%s', '-ascii');\n", filename.c_str());
+    StringAppendF(
+        &matlab_script, "tmp = load('%s', '-ascii');\n", filename.c_str());
     StringAppendF(
         &matlab_script,
         "lsqp.A = sparse(tmp(:, 1) + 1, tmp(:, 2) + 1, tmp(:, 3), %d, %d);\n",
@@ -679,26 +673,25 @@
         A->num_cols());
   }
 
-
   if (D != NULL) {
     string filename = filename_base + "_D.txt";
     WriteArrayToFileOrDie(filename, D, A->num_cols());
-    StringAppendF(&matlab_script,
-                  "lsqp.D = load('%s', '-ascii');\n", filename.c_str());
+    StringAppendF(
+        &matlab_script, "lsqp.D = load('%s', '-ascii');\n", filename.c_str());
   }
 
   if (b != NULL) {
     string filename = filename_base + "_b.txt";
     WriteArrayToFileOrDie(filename, b, A->num_rows());
-    StringAppendF(&matlab_script,
-                  "lsqp.b = load('%s', '-ascii');\n", filename.c_str());
+    StringAppendF(
+        &matlab_script, "lsqp.b = load('%s', '-ascii');\n", filename.c_str());
   }
 
   if (x != NULL) {
     string filename = filename_base + "_x.txt";
     WriteArrayToFileOrDie(filename, x, A->num_cols());
-    StringAppendF(&matlab_script,
-                  "lsqp.x = load('%s', '-ascii');\n", filename.c_str());
+    StringAppendF(
+        &matlab_script, "lsqp.x = load('%s', '-ascii');\n", filename.c_str());
   }
 
   string matlab_filename = filename_base + ".m";
@@ -716,12 +709,11 @@
                                    int num_eliminate_blocks) {
   switch (dump_format_type) {
     case CONSOLE:
-      return DumpLinearLeastSquaresProblemToConsole(A, D, b, x,
-                                                    num_eliminate_blocks);
+      return DumpLinearLeastSquaresProblemToConsole(
+          A, D, b, x, num_eliminate_blocks);
     case TEXTFILE:
-      return DumpLinearLeastSquaresProblemToTextFile(filename_base,
-                                                     A, D, b, x,
-                                                     num_eliminate_blocks);
+      return DumpLinearLeastSquaresProblemToTextFile(
+          filename_base, A, D, b, x, num_eliminate_blocks);
     default:
       LOG(FATAL) << "Unknown DumpFormatType " << dump_format_type;
   }
diff --git a/internal/ceres/linear_least_squares_problems.h b/internal/ceres/linear_least_squares_problems.h
index 5dfcd34..cddaa9f 100644
--- a/internal/ceres/linear_least_squares_problems.h
+++ b/internal/ceres/linear_least_squares_problems.h
@@ -34,18 +34,17 @@
 #include <memory>
 #include <string>
 #include <vector>
-#include "ceres/sparse_matrix.h"
+
 #include "ceres/internal/port.h"
+#include "ceres/sparse_matrix.h"
 
 namespace ceres {
 namespace internal {
 
 // Structure defining a linear least squares problem and if possible
 // ground truth solutions. To be used by various LinearSolver tests.
-struct LinearLeastSquaresProblem {
-  LinearLeastSquaresProblem()
-      : num_eliminate_blocks(0) {
-  }
+struct CERES_EXPORT_INTERNAL LinearLeastSquaresProblem {
+  LinearLeastSquaresProblem() : num_eliminate_blocks(0) {}
 
   std::unique_ptr<SparseMatrix> A;
   std::unique_ptr<double[]> b;
@@ -61,7 +60,8 @@
 };
 
 // Factories for linear least squares problem.
-LinearLeastSquaresProblem* CreateLinearLeastSquaresProblemFromId(int id);
+CERES_EXPORT_INTERNAL LinearLeastSquaresProblem*
+CreateLinearLeastSquaresProblemFromId(int id);
 
 LinearLeastSquaresProblem* LinearLeastSquaresProblem0();
 LinearLeastSquaresProblem* LinearLeastSquaresProblem1();
diff --git a/internal/ceres/linear_operator.cc b/internal/ceres/linear_operator.cc
index 9d291bd..548c724 100644
--- a/internal/ceres/linear_operator.cc
+++ b/internal/ceres/linear_operator.cc
@@ -33,8 +33,7 @@
 namespace ceres {
 namespace internal {
 
-LinearOperator::~LinearOperator() {
-}
+LinearOperator::~LinearOperator() {}
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/linear_operator.h b/internal/ceres/linear_operator.h
index 6463fb5..9c59fc3 100644
--- a/internal/ceres/linear_operator.h
+++ b/internal/ceres/linear_operator.h
@@ -33,6 +33,7 @@
 #ifndef CERES_INTERNAL_LINEAR_OPERATOR_H_
 #define CERES_INTERNAL_LINEAR_OPERATOR_H_
 
+#include "ceres/internal/port.h"
 #include "ceres/types.h"
 
 namespace ceres {
@@ -40,7 +41,7 @@
 
 // This is an abstract base class for linear operators. It supports
 // access to size information and left and right multiply operators.
-class LinearOperator {
+class CERES_EXPORT_INTERNAL LinearOperator {
  public:
   virtual ~LinearOperator();
 
diff --git a/internal/ceres/linear_solver.cc b/internal/ceres/linear_solver.cc
index 107af6a..6cae248 100644
--- a/internal/ceres/linear_solver.cc
+++ b/internal/ceres/linear_solver.cc
@@ -33,9 +33,9 @@
 #include "ceres/cgnr_solver.h"
 #include "ceres/dense_normal_cholesky_solver.h"
 #include "ceres/dense_qr_solver.h"
+#include "ceres/dynamic_sparse_normal_cholesky_solver.h"
 #include "ceres/iterative_schur_complement_solver.h"
 #include "ceres/schur_complement_solver.h"
-#include "ceres/dynamic_sparse_normal_cholesky_solver.h"
 #include "ceres/sparse_normal_cholesky_solver.h"
 #include "ceres/types.h"
 #include "glog/logging.h"
@@ -43,8 +43,7 @@
 namespace ceres {
 namespace internal {
 
-LinearSolver::~LinearSolver() {
-}
+LinearSolver::~LinearSolver() {}
 
 LinearSolverType LinearSolver::LinearSolverForZeroEBlocks(
     LinearSolverType linear_solver_type) {
@@ -112,8 +111,7 @@
       return new DenseNormalCholeskySolver(options);
 
     default:
-      LOG(FATAL) << "Unknown linear solver type :"
-                 << options.type;
+      LOG(FATAL) << "Unknown linear solver type :" << options.type;
       return NULL;  // MSVC doesn't understand that LOG(FATAL) never returns.
   }
 }
diff --git a/internal/ceres/linear_solver.h b/internal/ceres/linear_solver.h
index 24c245d..49c6527 100644
--- a/internal/ceres/linear_solver.h
+++ b/internal/ceres/linear_solver.h
@@ -38,12 +38,14 @@
 #include <map>
 #include <string>
 #include <vector>
+
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/casts.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/context_impl.h"
 #include "ceres/dense_sparse_matrix.h"
 #include "ceres/execution_summary.h"
+#include "ceres/internal/port.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
 #include "glog/logging.h"
@@ -74,11 +76,11 @@
 // algebra library should use before computing a sparse factorization
 // (usually Cholesky).
 enum OrderingType {
-  NATURAL, // Do not re-order the matrix. This is useful when the
-           // matrix has been ordered using a fill-reducing ordering
-           // already.
-  AMD      // Use the Approximate Minimum Degree algorithm to re-order
-           // the matrix.
+  NATURAL,  // Do not re-order the matrix. This is useful when the
+            // matrix has been ordered using a fill-reducing ordering
+            // already.
+  AMD       // Use the Approximate Minimum Degree algorithm to re-order
+            // the matrix.
 };
 
 class LinearOperator;
@@ -99,7 +101,7 @@
 // The Options struct configures the LinearSolver object for its
 // lifetime. The PerSolveOptions struct is used to specify options for
 // a particular Solve call.
-class LinearSolver {
+class CERES_EXPORT_INTERNAL LinearSolver {
  public:
   struct Options {
     LinearSolverType type = SPARSE_NORMAL_CHOLESKY;
@@ -162,6 +164,7 @@
 
     bool use_mixed_precision_solves = false;
     int max_num_refinement_iterations = 0;
+    int subset_preconditioner_start_row_block = -1;
     ContextImpl* context = nullptr;
   };
 
@@ -214,7 +217,6 @@
     // used a preconditioner.
     LinearOperator* preconditioner = nullptr;
 
-
     // The following tolerance related options only makes sense for
     // iterative solvers. Direct solvers ignore them.
 
@@ -328,10 +330,12 @@
 
 // Linear solvers that depend on acccess to the low level structure of
 // a SparseMatrix.
+// clang-format off
 typedef TypedLinearSolver<BlockSparseMatrix>         BlockSparseMatrixSolver;          // NOLINT
 typedef TypedLinearSolver<CompressedRowSparseMatrix> CompressedRowSparseMatrixSolver;  // NOLINT
 typedef TypedLinearSolver<DenseSparseMatrix>         DenseSparseMatrixSolver;          // NOLINT
 typedef TypedLinearSolver<TripletSparseMatrix>       TripletSparseMatrixSolver;        // NOLINT
+// clang-format on
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/local_parameterization.cc b/internal/ceres/local_parameterization.cc
index a7fe4a1..62947f0 100644
--- a/internal/ceres/local_parameterization.cc
+++ b/internal/ceres/local_parameterization.cc
@@ -31,10 +31,11 @@
 #include "ceres/local_parameterization.h"
 
 #include <algorithm>
+
 #include "Eigen/Geometry"
-#include "ceres/householder_vector.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/fixed_array.h"
+#include "ceres/internal/householder_vector.h"
 #include "ceres/rotation.h"
 #include "glog/logging.h"
 
@@ -42,8 +43,7 @@
 
 using std::vector;
 
-LocalParameterization::~LocalParameterization() {
-}
+LocalParameterization::~LocalParameterization() {}
 
 bool LocalParameterization::MultiplyByJacobian(const double* x,
                                                const int num_rows,
@@ -86,15 +86,18 @@
                                                   const int num_cols,
                                                   const double* global_matrix,
                                                   double* local_matrix) const {
-  std::copy(global_matrix,
-            global_matrix + num_cols * GlobalSize(),
-            local_matrix);
+  std::copy(
+      global_matrix, global_matrix + num_cols * GlobalSize(), local_matrix);
   return true;
 }
 
 SubsetParameterization::SubsetParameterization(
     int size, const vector<int>& constant_parameters)
     : local_size_(size - constant_parameters.size()), constancy_mask_(size, 0) {
+  if (constant_parameters.empty()) {
+    return;
+  }
+
   vector<int> constant = constant_parameters;
   std::sort(constant.begin(), constant.end());
   CHECK_GE(constant.front(), 0) << "Indices indicating constant parameter must "
@@ -141,19 +144,19 @@
 }
 
 bool SubsetParameterization::MultiplyByJacobian(const double* x,
-                                               const int num_rows,
-                                               const double* global_matrix,
-                                               double* local_matrix) const {
+                                                const int num_cols,
+                                                const double* global_matrix,
+                                                double* local_matrix) const {
   if (local_size_ == 0) {
     return true;
   }
 
   const int global_size = GlobalSize();
-  for (int row = 0; row < num_rows; ++row) {
-    for (int col = 0, j = 0; col < global_size; ++col) {
-      if (!constancy_mask_[col]) {
-        local_matrix[row * local_size_ + j++] =
-            global_matrix[row * global_size + col];
+  for (int col = 0; col < num_cols; ++col) {
+    for (int i = 0, j = 0; i < global_size; ++i) {
+      if (!constancy_mask_[i]) {
+        local_matrix[col * local_size_ + j++] =
+            global_matrix[col * global_size + i];
       }
     }
   }
@@ -183,10 +186,12 @@
 
 bool QuaternionParameterization::ComputeJacobian(const double* x,
                                                  double* jacobian) const {
-  jacobian[0] = -x[1]; jacobian[1]  = -x[2]; jacobian[2]  = -x[3];  // NOLINT
-  jacobian[3] =  x[0]; jacobian[4]  =  x[3]; jacobian[5]  = -x[2];  // NOLINT
-  jacobian[6] = -x[3]; jacobian[7]  =  x[0]; jacobian[8]  =  x[1];  // NOLINT
-  jacobian[9] =  x[2]; jacobian[10] = -x[1]; jacobian[11] =  x[0];  // NOLINT
+  // clang-format off
+  jacobian[0] = -x[1];  jacobian[1]  = -x[2];   jacobian[2]  = -x[3];
+  jacobian[3] =  x[0];  jacobian[4]  =  x[3];   jacobian[5]  = -x[2];
+  jacobian[6] = -x[3];  jacobian[7]  =  x[0];   jacobian[8]  =  x[1];
+  jacobian[9] =  x[2];  jacobian[10] = -x[1];   jacobian[11] =  x[0];
+  // clang-format on
   return true;
 }
 
@@ -216,10 +221,12 @@
 
 bool EigenQuaternionParameterization::ComputeJacobian(const double* x,
                                                       double* jacobian) const {
-  jacobian[0] =  x[3]; jacobian[1]  =  x[2]; jacobian[2]  = -x[1];  // NOLINT
-  jacobian[3] = -x[2]; jacobian[4]  =  x[3]; jacobian[5]  =  x[0];  // NOLINT
-  jacobian[6] =  x[1]; jacobian[7]  = -x[0]; jacobian[8]  =  x[3];  // NOLINT
-  jacobian[9] = -x[0]; jacobian[10] = -x[1]; jacobian[11] = -x[2];  // NOLINT
+  // clang-format off
+  jacobian[0] =  x[3];  jacobian[1]  =  x[2];  jacobian[2]  = -x[1];
+  jacobian[3] = -x[2];  jacobian[4]  =  x[3];  jacobian[5]  =  x[0];
+  jacobian[6] =  x[1];  jacobian[7]  = -x[0];  jacobian[8]  =  x[3];
+  jacobian[9] = -x[0];  jacobian[10] = -x[1];  jacobian[11] = -x[2];
+  // clang-format on
   return true;
 }
 
@@ -248,21 +255,26 @@
   // (2nd Edition) for a detailed description.  Note there is a typo on Page
   // 625, line 4 so check the book errata.
   const double norm_delta_div_2 = 0.5 * norm_delta;
-  const double sin_delta_by_delta = sin(norm_delta_div_2) /
-      norm_delta_div_2;
+  const double sin_delta_by_delta =
+      std::sin(norm_delta_div_2) / norm_delta_div_2;
 
   Vector y(size_);
   y.head(size_ - 1) = 0.5 * sin_delta_by_delta * delta;
-  y(size_ - 1) = cos(norm_delta_div_2);
+  y(size_ - 1) = std::cos(norm_delta_div_2);
 
   Vector v(size_);
   double beta;
-  internal::ComputeHouseholderVector<double>(x, &v, &beta);
+
+  // NOTE: The explicit template arguments are needed here because
+  // ComputeHouseholderVector is templated and some versions of MSVC
+  // have trouble deducing the type of v automatically.
+  internal::ComputeHouseholderVector<ConstVectorRef, double, Eigen::Dynamic>(
+      x, &v, &beta);
 
   // Apply the delta update to remain on the unit sphere. See section A6.9.3
   // on page 625 of Hartley & Zisserman (2nd Edition) for a detailed
   // description.
-  x_plus_delta = x.norm() * (y -  v * (beta * (v.transpose() * y)));
+  x_plus_delta = x.norm() * (y - v * (beta * (v.transpose() * y)));
 
   return true;
 }
@@ -274,7 +286,12 @@
 
   Vector v(size_);
   double beta;
-  internal::ComputeHouseholderVector<double>(x, &v, &beta);
+
+  // NOTE: The explicit template arguments are needed here because
+  // ComputeHouseholderVector is templated and some versions of MSVC
+  // have trouble deducing the type of v automatically.
+  internal::ComputeHouseholderVector<ConstVectorRef, double, Eigen::Dynamic>(
+      x, &v, &beta);
 
   // The Jacobian is equal to J = 0.5 * H.leftCols(size_ - 1) where H is the
   // Householder matrix (H = I - beta * v * v').
@@ -287,65 +304,14 @@
   return true;
 }
 
-ProductParameterization::ProductParameterization(
-    LocalParameterization* local_param1,
-    LocalParameterization* local_param2) {
-  local_params_.push_back(local_param1);
-  local_params_.push_back(local_param2);
-  Init();
-}
-
-ProductParameterization::ProductParameterization(
-    LocalParameterization* local_param1,
-    LocalParameterization* local_param2,
-    LocalParameterization* local_param3) {
-  local_params_.push_back(local_param1);
-  local_params_.push_back(local_param2);
-  local_params_.push_back(local_param3);
-  Init();
-}
-
-ProductParameterization::ProductParameterization(
-    LocalParameterization* local_param1,
-    LocalParameterization* local_param2,
-    LocalParameterization* local_param3,
-    LocalParameterization* local_param4) {
-  local_params_.push_back(local_param1);
-  local_params_.push_back(local_param2);
-  local_params_.push_back(local_param3);
-  local_params_.push_back(local_param4);
-  Init();
-}
-
-ProductParameterization::~ProductParameterization() {
-  for (int i = 0; i < local_params_.size(); ++i) {
-    delete local_params_[i];
-  }
-}
-
-void ProductParameterization::Init() {
-  global_size_ = 0;
-  local_size_ = 0;
-  buffer_size_ = 0;
-  for (int i = 0; i < local_params_.size(); ++i) {
-    const LocalParameterization* param = local_params_[i];
-    buffer_size_ = std::max(buffer_size_,
-                            param->LocalSize() * param->GlobalSize());
-    global_size_ += param->GlobalSize();
-    local_size_ += param->LocalSize();
-  }
-}
-
 bool ProductParameterization::Plus(const double* x,
                                    const double* delta,
                                    double* x_plus_delta) const {
   int x_cursor = 0;
   int delta_cursor = 0;
-  for (int i = 0; i < local_params_.size(); ++i) {
-    const LocalParameterization* param = local_params_[i];
-    if (!param->Plus(x + x_cursor,
-                     delta + delta_cursor,
-                     x_plus_delta + x_cursor)) {
+  for (const auto& param : local_params_) {
+    if (!param->Plus(
+            x + x_cursor, delta + delta_cursor, x_plus_delta + x_cursor)) {
       return false;
     }
     delta_cursor += param->LocalSize();
@@ -363,16 +329,15 @@
 
   int x_cursor = 0;
   int delta_cursor = 0;
-  for (int i = 0; i < local_params_.size(); ++i) {
-    const LocalParameterization* param = local_params_[i];
+  for (const auto& param : local_params_) {
     const int local_size = param->LocalSize();
     const int global_size = param->GlobalSize();
 
-    if (!param->ComputeJacobian(x + x_cursor, buffer.get())) {
+    if (!param->ComputeJacobian(x + x_cursor, buffer.data())) {
       return false;
     }
-    jacobian.block(x_cursor, delta_cursor, global_size, local_size)
-        = MatrixRef(buffer.get(), global_size, local_size);
+    jacobian.block(x_cursor, delta_cursor, global_size, local_size) =
+        MatrixRef(buffer.data(), global_size, local_size);
 
     delta_cursor += local_size;
     x_cursor += global_size;
diff --git a/internal/ceres/local_parameterization_test.cc b/internal/ceres/local_parameterization_test.cc
index 18b7e8c..ec8e660 100644
--- a/internal/ceres/local_parameterization_test.cc
+++ b/internal/ceres/local_parameterization_test.cc
@@ -28,16 +28,17 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/local_parameterization.h"
+
 #include <cmath>
 #include <limits>
 #include <memory>
 
 #include "Eigen/Geometry"
 #include "ceres/autodiff_local_parameterization.h"
-#include "ceres/householder_vector.h"
 #include "ceres/internal/autodiff.h"
 #include "ceres/internal/eigen.h"
-#include "ceres/local_parameterization.h"
+#include "ceres/internal/householder_vector.h"
 #include "ceres/random.h"
 #include "ceres/rotation.h"
 #include "gtest/gtest.h"
@@ -69,13 +70,37 @@
 
   Matrix global_matrix = Matrix::Ones(10, 3);
   Matrix local_matrix = Matrix::Zero(10, 3);
-  parameterization.MultiplyByJacobian(x,
-                                      10,
-                                      global_matrix.data(),
-                                      local_matrix.data());
+  parameterization.MultiplyByJacobian(
+      x, 10, global_matrix.data(), local_matrix.data());
   EXPECT_EQ((local_matrix - global_matrix).norm(), 0.0);
 }
 
+TEST(SubsetParameterization, EmptyConstantParameters) {
+  std::vector<int> constant_parameters;
+  SubsetParameterization parameterization(3, constant_parameters);
+  EXPECT_EQ(parameterization.GlobalSize(), 3);
+  EXPECT_EQ(parameterization.LocalSize(), 3);
+  double x[3] = {1, 2, 3};
+  double delta[3] = {4, 5, 6};
+  double x_plus_delta[3] = {-1, -2, -3};
+  parameterization.Plus(x, delta, x_plus_delta);
+  EXPECT_EQ(x_plus_delta[0], x[0] + delta[0]);
+  EXPECT_EQ(x_plus_delta[1], x[1] + delta[1]);
+  EXPECT_EQ(x_plus_delta[2], x[2] + delta[2]);
+
+  Matrix jacobian(3, 3);
+  Matrix expected_jacobian(3, 3);
+  expected_jacobian.setIdentity();
+  parameterization.ComputeJacobian(x, jacobian.data());
+  EXPECT_EQ(jacobian, expected_jacobian);
+
+  Matrix global_matrix(3, 5);
+  global_matrix.setRandom();
+  Matrix local_matrix(3, 5);
+  parameterization.MultiplyByJacobian(
+      x, 5, global_matrix.data(), local_matrix.data());
+  EXPECT_EQ(global_matrix, local_matrix);
+}
 
 TEST(SubsetParameterization, NegativeParameterIndexDeathTest) {
   std::vector<int> constant_parameters;
@@ -161,7 +186,7 @@
     parameterization.Plus(x, delta, x_plus_delta);
     int k = 0;
     for (int j = 0; j < kGlobalSize; ++j) {
-      if (j == i)  {
+      if (j == i) {
         EXPECT_EQ(x_plus_delta[j], x[j]);
       } else {
         EXPECT_EQ(x_plus_delta[j], x[j] + delta[k++]);
@@ -193,10 +218,8 @@
     }
 
     Matrix local_matrix = Matrix::Zero(10, kLocalSize);
-    parameterization.MultiplyByJacobian(x,
-                                        10,
-                                        global_matrix.data(),
-                                        local_matrix.data());
+    parameterization.MultiplyByJacobian(
+        x, 10, global_matrix.data(), local_matrix.data());
     Matrix expected_local_matrix =
         global_matrix * MatrixRef(jacobian, kGlobalSize, kLocalSize);
     EXPECT_EQ((local_matrix - expected_local_matrix).norm(), 0.0);
@@ -206,7 +229,7 @@
 // Functor needed to implement automatically differentiated Plus for
 // quaternions.
 struct QuaternionPlus {
-  template<typename T>
+  template <typename T>
   bool operator()(const T* x, const T* delta, T* x_plus_delta) const {
     const T squared_norm_delta =
         delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2];
@@ -235,10 +258,10 @@
   }
 };
 
-template<typename Parameterization, typename Plus>
-void QuaternionParameterizationTestHelper(
-    const double* x, const double* delta,
-    const double* x_plus_delta_ref) {
+template <typename Parameterization, typename Plus>
+void QuaternionParameterizationTestHelper(const double* x,
+                                          const double* delta,
+                                          const double* x_plus_delta_ref) {
   const int kGlobalSize = 4;
   const int kLocalSize = 3;
 
@@ -251,34 +274,28 @@
     EXPECT_NEAR(x_plus_delta[i], x_plus_delta[i], kTolerance);
   }
 
-  const double x_plus_delta_norm =
-      sqrt(x_plus_delta[0] * x_plus_delta[0] +
-           x_plus_delta[1] * x_plus_delta[1] +
-           x_plus_delta[2] * x_plus_delta[2] +
-           x_plus_delta[3] * x_plus_delta[3]);
+  const double x_plus_delta_norm = sqrt(
+      x_plus_delta[0] * x_plus_delta[0] + x_plus_delta[1] * x_plus_delta[1] +
+      x_plus_delta[2] * x_plus_delta[2] + x_plus_delta[3] * x_plus_delta[3]);
 
   EXPECT_NEAR(x_plus_delta_norm, 1.0, kTolerance);
 
   double jacobian_ref[12];
   double zero_delta[kLocalSize] = {0.0, 0.0, 0.0};
   const double* parameters[2] = {x, zero_delta};
-  double* jacobian_array[2] = { NULL, jacobian_ref };
+  double* jacobian_array[2] = {NULL, jacobian_ref};
 
   // Autodiff jacobian at delta_x = 0.
-  internal::AutoDifferentiate<StaticParameterDims<kGlobalSize, kLocalSize>>(
-      Plus(),
-      parameters,
-      kGlobalSize,
-      x_plus_delta,
-      jacobian_array);
+  internal::AutoDifferentiate<kGlobalSize,
+                              StaticParameterDims<kGlobalSize, kLocalSize>>(
+      Plus(), parameters, kGlobalSize, x_plus_delta, jacobian_array);
 
   double jacobian[12];
   parameterization.ComputeJacobian(x, jacobian);
   for (int i = 0; i < 12; ++i) {
     EXPECT_TRUE(IsFinite(jacobian[i]));
     EXPECT_NEAR(jacobian[i], jacobian_ref[i], kTolerance)
-        << "Jacobian mismatch: i = " << i
-        << "\n Expected \n"
+        << "Jacobian mismatch: i = " << i << "\n Expected \n"
         << ConstMatrixRef(jacobian_ref, kGlobalSize, kLocalSize)
         << "\n Actual \n"
         << ConstMatrixRef(jacobian, kGlobalSize, kLocalSize);
@@ -286,10 +303,8 @@
 
   Matrix global_matrix = Matrix::Random(10, kGlobalSize);
   Matrix local_matrix = Matrix::Zero(10, kLocalSize);
-  parameterization.MultiplyByJacobian(x,
-                                      10,
-                                      global_matrix.data(),
-                                      local_matrix.data());
+  parameterization.MultiplyByJacobian(
+      x, 10, global_matrix.data(), local_matrix.data());
   Matrix expected_local_matrix =
       global_matrix * MatrixRef(jacobian, kGlobalSize, kLocalSize);
   EXPECT_NEAR((local_matrix - expected_local_matrix).norm(),
@@ -338,9 +353,8 @@
   Normalize<4>(x);
 
   double delta[3] = {0.24, 0.15, 0.10};
-  const double delta_norm = sqrt(delta[0] * delta[0] +
-                                 delta[1] * delta[1] +
-                                 delta[2] * delta[2]);
+  const double delta_norm =
+      sqrt(delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2]);
   double q_delta[4];
   q_delta[0] = cos(delta_norm);
   q_delta[1] = sin(delta_norm) / delta_norm * delta[0];
@@ -356,7 +370,7 @@
 // Functor needed to implement automatically differentiated Plus for
 // Eigen's quaternion.
 struct EigenQuaternionPlus {
-  template<typename T>
+  template <typename T>
   bool operator()(const T* x, const T* delta, T* x_plus_delta) const {
     const T norm_delta =
         sqrt(delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2]);
@@ -372,7 +386,7 @@
       // constant and when used for automatic differentiation will
       // lead to a zero derivative. Instead we take a first order
       // approximation and evaluate it at zero.
-      q_delta.coeffs() <<  delta[0], delta[1], delta[2], T(1.0);
+      q_delta.coeffs() << delta[0], delta[1], delta[2], T(1.0);
     }
 
     Eigen::Map<Eigen::Quaternion<T>> x_plus_delta_ref(x_plus_delta);
@@ -415,9 +429,8 @@
   x.normalize();
 
   double delta[3] = {0.24, 0.15, 0.10};
-  const double delta_norm = sqrt(delta[0] * delta[0] +
-                                 delta[1] * delta[1] +
-                                 delta[2] * delta[2]);
+  const double delta_norm =
+      sqrt(delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2]);
 
   // Note: w is first in the constructor.
   Eigen::Quaterniond q_delta(cos(delta_norm),
@@ -432,44 +445,48 @@
 }
 
 // Functor needed to implement automatically differentiated Plus for
-// homogeneous vectors. Note this explicitly defined for vectors of size 4.
+// homogeneous vectors.
+template <int Dim>
 struct HomogeneousVectorParameterizationPlus {
-  template<typename Scalar>
-  bool operator()(const Scalar* p_x, const Scalar* p_delta,
+  template <typename Scalar>
+  bool operator()(const Scalar* p_x,
+                  const Scalar* p_delta,
                   Scalar* p_x_plus_delta) const {
-    Eigen::Map<const Eigen::Matrix<Scalar, 4, 1>> x(p_x);
-    Eigen::Map<const Eigen::Matrix<Scalar, 3, 1>> delta(p_delta);
-    Eigen::Map<Eigen::Matrix<Scalar, 4, 1>> x_plus_delta(p_x_plus_delta);
+    Eigen::Map<const Eigen::Matrix<Scalar, Dim, 1>> x(p_x);
+    Eigen::Map<const Eigen::Matrix<Scalar, Dim - 1, 1>> delta(p_delta);
+    Eigen::Map<Eigen::Matrix<Scalar, Dim, 1>> x_plus_delta(p_x_plus_delta);
 
-    const Scalar squared_norm_delta =
-        delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2];
+    const Scalar squared_norm_delta = delta.squaredNorm();
 
-    Eigen::Matrix<Scalar, 4, 1> y;
+    Eigen::Matrix<Scalar, Dim, 1> y;
     Scalar one_half(0.5);
     if (squared_norm_delta > Scalar(0.0)) {
       Scalar norm_delta = sqrt(squared_norm_delta);
       Scalar norm_delta_div_2 = 0.5 * norm_delta;
-      const Scalar sin_delta_by_delta = sin(norm_delta_div_2) /
-          norm_delta_div_2;
-      y[0] = sin_delta_by_delta * delta[0] * one_half;
-      y[1] = sin_delta_by_delta * delta[1] * one_half;
-      y[2] = sin_delta_by_delta * delta[2] * one_half;
-      y[3] = cos(norm_delta_div_2);
+      const Scalar sin_delta_by_delta =
+          sin(norm_delta_div_2) / norm_delta_div_2;
+      y.template head<Dim - 1>() = sin_delta_by_delta * one_half * delta;
+      y[Dim - 1] = cos(norm_delta_div_2);
 
     } else {
       // We do not just use y = [0,0,0,1] here because that is a
       // constant and when used for automatic differentiation will
       // lead to a zero derivative. Instead we take a first order
       // approximation and evaluate it at zero.
-      y[0] = delta[0] * one_half;
-      y[1] = delta[1] * one_half;
-      y[2] = delta[2] * one_half;
-      y[3] = Scalar(1.0);
+      y.template head<Dim - 1>() = delta * one_half;
+      y[Dim - 1] = Scalar(1.0);
     }
 
-    Eigen::Matrix<Scalar, Eigen::Dynamic, 1> v(4);
+    Eigen::Matrix<Scalar, Dim, 1> v;
     Scalar beta;
-    internal::ComputeHouseholderVector<Scalar>(x, &v, &beta);
+
+    // NOTE: The explicit template arguments are needed here because
+    // ComputeHouseholderVector is templated and some versions of MSVC
+    // have trouble deducing the type of v automatically.
+    internal::ComputeHouseholderVector<
+        Eigen::Map<const Eigen::Matrix<Scalar, Dim, 1>>,
+        Scalar,
+        Dim>(x, &v, &beta);
 
     x_plus_delta = x.norm() * (y - v * (beta * v.dot(y)));
 
@@ -477,8 +494,8 @@
   }
 };
 
-void HomogeneousVectorParameterizationHelper(const double* x,
-                                             const double* delta) {
+static void HomogeneousVectorParameterizationHelper(const double* x,
+                                                    const double* delta) {
   const double kTolerance = 1e-14;
 
   HomogeneousVectorParameterization homogeneous_vector_parameterization(4);
@@ -487,19 +504,17 @@
   double x_plus_delta[4] = {0.0, 0.0, 0.0, 0.0};
   homogeneous_vector_parameterization.Plus(x, delta, x_plus_delta);
 
-  const double x_plus_delta_norm =
-      sqrt(x_plus_delta[0] * x_plus_delta[0] +
-           x_plus_delta[1] * x_plus_delta[1] +
-           x_plus_delta[2] * x_plus_delta[2] +
-           x_plus_delta[3] * x_plus_delta[3]);
+  const double x_plus_delta_norm = sqrt(
+      x_plus_delta[0] * x_plus_delta[0] + x_plus_delta[1] * x_plus_delta[1] +
+      x_plus_delta[2] * x_plus_delta[2] + x_plus_delta[3] * x_plus_delta[3]);
 
-  const double x_norm = sqrt(x[0] * x[0] + x[1] * x[1] +
-                             x[2] * x[2] + x[3] * x[3]);
+  const double x_norm =
+      sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2] + x[3] * x[3]);
 
   EXPECT_NEAR(x_plus_delta_norm, x_norm, kTolerance);
 
   // Autodiff jacobian at delta_x = 0.
-  AutoDiffLocalParameterization<HomogeneousVectorParameterizationPlus, 4, 3>
+  AutoDiffLocalParameterization<HomogeneousVectorParameterizationPlus<4>, 4, 3>
       autodiff_jacobian;
 
   double jacobian_autodiff[12];
@@ -580,34 +595,211 @@
   EXPECT_DEATH_IF_SUPPORTED(HomogeneousVectorParameterization x(1), "size");
 }
 
+// Functor needed to implement automatically differentiated Plus for
+// line parameterization.
+template <int AmbientSpaceDim>
+struct LineParameterizationPlus {
+  template <typename Scalar>
+  bool operator()(const Scalar* p_x,
+                  const Scalar* p_delta,
+                  Scalar* p_x_plus_delta) const {
+    static constexpr int kTangetSpaceDim = AmbientSpaceDim - 1;
+    Eigen::Map<const Eigen::Matrix<Scalar, AmbientSpaceDim, 1>> origin_point(
+        p_x);
+    Eigen::Map<const Eigen::Matrix<Scalar, AmbientSpaceDim, 1>> dir(
+        p_x + AmbientSpaceDim);
+    Eigen::Map<const Eigen::Matrix<Scalar, kTangetSpaceDim, 1>>
+        delta_origin_point(p_delta);
+    Eigen::Map<Eigen::Matrix<Scalar, AmbientSpaceDim, 1>>
+        origin_point_plus_delta(p_x_plus_delta);
+
+    HomogeneousVectorParameterizationPlus<AmbientSpaceDim> dir_plus;
+    dir_plus(dir.data(),
+             p_delta + kTangetSpaceDim,
+             p_x_plus_delta + AmbientSpaceDim);
+
+    Eigen::Matrix<Scalar, AmbientSpaceDim, 1> v;
+    Scalar beta;
+
+    // NOTE: The explicit template arguments are needed here because
+    // ComputeHouseholderVector is templated and some versions of MSVC
+    // have trouble deducing the type of v automatically.
+    internal::ComputeHouseholderVector<
+        Eigen::Map<const Eigen::Matrix<Scalar, AmbientSpaceDim, 1>>,
+        Scalar,
+        AmbientSpaceDim>(dir, &v, &beta);
+
+    Eigen::Matrix<Scalar, AmbientSpaceDim, 1> y;
+    y << 0.5 * delta_origin_point, Scalar(0.0);
+    origin_point_plus_delta = origin_point + y - v * (beta * v.dot(y));
+
+    return true;
+  }
+};
+
+template <int AmbientSpaceDim>
+static void LineParameterizationHelper(const double* x_ptr,
+                                       const double* delta) {
+  const double kTolerance = 1e-14;
+
+  static constexpr int ParameterDim = 2 * AmbientSpaceDim;
+  static constexpr int TangientParameterDim = 2 * (AmbientSpaceDim - 1);
+
+  LineParameterization<AmbientSpaceDim> line_parameterization;
+
+  using ParameterVector = Eigen::Matrix<double, ParameterDim, 1>;
+  ParameterVector x_plus_delta = ParameterVector::Zero();
+  line_parameterization.Plus(x_ptr, delta, x_plus_delta.data());
+
+  // Ensure the update maintains the norm for the line direction.
+  Eigen::Map<const ParameterVector> x(x_ptr);
+  const double dir_plus_delta_norm =
+      x_plus_delta.template tail<AmbientSpaceDim>().norm();
+  const double dir_norm = x.template tail<AmbientSpaceDim>().norm();
+  EXPECT_NEAR(dir_plus_delta_norm, dir_norm, kTolerance);
+
+  // Ensure the update of the origin point is perpendicular to the line
+  // direction.
+  const double dot_prod_val = x.template tail<AmbientSpaceDim>().dot(
+      x_plus_delta.template head<AmbientSpaceDim>() -
+      x.template head<AmbientSpaceDim>());
+  EXPECT_NEAR(dot_prod_val, 0.0, kTolerance);
+
+  // Autodiff jacobian at delta_x = 0.
+  AutoDiffLocalParameterization<LineParameterizationPlus<AmbientSpaceDim>,
+                                ParameterDim,
+                                TangientParameterDim>
+      autodiff_jacobian;
+
+  using JacobianMatrix = Eigen::
+      Matrix<double, ParameterDim, TangientParameterDim, Eigen::RowMajor>;
+  constexpr double kNaN = std::numeric_limits<double>::quiet_NaN();
+  JacobianMatrix jacobian_autodiff = JacobianMatrix::Constant(kNaN);
+  JacobianMatrix jacobian_analytic = JacobianMatrix::Constant(kNaN);
+
+  autodiff_jacobian.ComputeJacobian(x_ptr, jacobian_autodiff.data());
+  line_parameterization.ComputeJacobian(x_ptr, jacobian_analytic.data());
+
+  EXPECT_FALSE(jacobian_autodiff.hasNaN());
+  EXPECT_FALSE(jacobian_analytic.hasNaN());
+  EXPECT_TRUE(jacobian_autodiff.isApprox(jacobian_analytic))
+      << "auto diff:\n"
+      << jacobian_autodiff << "\n"
+      << "analytic diff:\n"
+      << jacobian_analytic;
+}
+
+TEST(LineParameterization, ZeroTest3D) {
+  double x[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 1.0};
+  double delta[4] = {0.0, 0.0, 0.0, 0.0};
+
+  LineParameterizationHelper<3>(x, delta);
+}
+
+TEST(LineParameterization, ZeroTest4D) {
+  double x[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0};
+  double delta[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+  LineParameterizationHelper<4>(x, delta);
+}
+
+TEST(LineParameterization, ZeroOriginPointTest3D) {
+  double x[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 1.0};
+  double delta[4] = {0.0, 0.0, 1.0, 2.0};
+
+  LineParameterizationHelper<3>(x, delta);
+}
+
+TEST(LineParameterization, ZeroOriginPointTest4D) {
+  double x[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0};
+  double delta[6] = {0.0, 0.0, 0.0, 1.0, 2.0, 3.0};
+
+  LineParameterizationHelper<4>(x, delta);
+}
+
+TEST(LineParameterization, ZeroDirTest3D) {
+  double x[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 1.0};
+  double delta[4] = {3.0, 2.0, 0.0, 0.0};
+
+  LineParameterizationHelper<3>(x, delta);
+}
+
+TEST(LineParameterization, ZeroDirTest4D) {
+  double x[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0};
+  double delta[6] = {3.0, 2.0, 1.0, 0.0, 0.0, 0.0};
+
+  LineParameterizationHelper<4>(x, delta);
+}
+
+TEST(LineParameterization, AwayFromZeroTest3D1) {
+  Eigen::Matrix<double, 6, 1> x;
+  x.head<3>() << 1.54, 2.32, 1.34;
+  x.tail<3>() << 0.52, 0.25, 0.15;
+  x.tail<3>().normalize();
+
+  double delta[4] = {4.0, 7.0, 1.0, -0.5};
+
+  LineParameterizationHelper<3>(x.data(), delta);
+}
+
+TEST(LineParameterization, AwayFromZeroTest4D1) {
+  Eigen::Matrix<double, 8, 1> x;
+  x.head<4>() << 1.54, 2.32, 1.34, 3.23;
+  x.tail<4>() << 0.52, 0.25, 0.15, 0.45;
+  x.tail<4>().normalize();
+
+  double delta[6] = {4.0, 7.0, -3.0, 0.0, 1.0, -0.5};
+
+  LineParameterizationHelper<4>(x.data(), delta);
+}
+
+TEST(LineParameterization, AwayFromZeroTest3D2) {
+  Eigen::Matrix<double, 6, 1> x;
+  x.head<3>() << 7.54, -2.81, 8.63;
+  x.tail<3>() << 2.52, 5.25, 4.15;
+
+  double delta[4] = {4.0, 7.0, 1.0, -0.5};
+
+  LineParameterizationHelper<3>(x.data(), delta);
+}
+
+TEST(LineParameterization, AwayFromZeroTest4D2) {
+  Eigen::Matrix<double, 8, 1> x;
+  x.head<4>() << 7.54, -2.81, 8.63, 6.93;
+  x.tail<4>() << 2.52, 5.25, 4.15, 1.45;
+
+  double delta[6] = {4.0, 7.0, -3.0, 2.0, 1.0, -0.5};
+
+  LineParameterizationHelper<4>(x.data(), delta);
+}
 
 class ProductParameterizationTest : public ::testing::Test {
- protected :
-  virtual void SetUp() {
+ protected:
+  void SetUp() final {
     const int global_size1 = 5;
     std::vector<int> constant_parameters1;
     constant_parameters1.push_back(2);
-    param1_.reset(new SubsetParameterization(global_size1,
-                                             constant_parameters1));
+    param1_.reset(
+        new SubsetParameterization(global_size1, constant_parameters1));
 
     const int global_size2 = 3;
     std::vector<int> constant_parameters2;
     constant_parameters2.push_back(0);
     constant_parameters2.push_back(1);
-    param2_.reset(new SubsetParameterization(global_size2,
-                                             constant_parameters2));
+    param2_.reset(
+        new SubsetParameterization(global_size2, constant_parameters2));
 
     const int global_size3 = 4;
     std::vector<int> constant_parameters3;
     constant_parameters3.push_back(1);
-    param3_.reset(new SubsetParameterization(global_size3,
-                                             constant_parameters3));
+    param3_.reset(
+        new SubsetParameterization(global_size3, constant_parameters3));
 
     const int global_size4 = 2;
     std::vector<int> constant_parameters4;
     constant_parameters4.push_back(1);
-    param4_.reset(new SubsetParameterization(global_size4,
-                                             constant_parameters4));
+    param4_.reset(
+        new SubsetParameterization(global_size4, constant_parameters4));
   }
 
   std::unique_ptr<LocalParameterization> param1_;
@@ -627,7 +819,6 @@
             param1->GlobalSize() + param2->GlobalSize());
 }
 
-
 TEST_F(ProductParameterizationTest, LocalAndGlobalSize3) {
   LocalParameterization* param1 = param1_.release();
   LocalParameterization* param2 = param2_.release();
@@ -648,15 +839,11 @@
 
   ProductParameterization product_param(param1, param2, param3, param4);
   EXPECT_EQ(product_param.LocalSize(),
-            param1->LocalSize() +
-            param2->LocalSize() +
-            param3->LocalSize() +
-            param4->LocalSize());
+            param1->LocalSize() + param2->LocalSize() + param3->LocalSize() +
+                param4->LocalSize());
   EXPECT_EQ(product_param.GlobalSize(),
-            param1->GlobalSize() +
-            param2->GlobalSize() +
-            param3->GlobalSize() +
-            param4->GlobalSize());
+            param1->GlobalSize() + param2->GlobalSize() + param3->GlobalSize() +
+                param4->GlobalSize());
 }
 
 TEST_F(ProductParameterizationTest, Plus) {
@@ -683,27 +870,23 @@
   int x_cursor = 0;
   int delta_cursor = 0;
 
-  EXPECT_TRUE(param1->Plus(&x[x_cursor],
-                           &delta[delta_cursor],
-                           &x_plus_delta[x_cursor]));
+  EXPECT_TRUE(param1->Plus(
+      &x[x_cursor], &delta[delta_cursor], &x_plus_delta[x_cursor]));
   x_cursor += param1->GlobalSize();
   delta_cursor += param1->LocalSize();
 
-  EXPECT_TRUE(param2->Plus(&x[x_cursor],
-                           &delta[delta_cursor],
-                           &x_plus_delta[x_cursor]));
+  EXPECT_TRUE(param2->Plus(
+      &x[x_cursor], &delta[delta_cursor], &x_plus_delta[x_cursor]));
   x_cursor += param2->GlobalSize();
   delta_cursor += param2->LocalSize();
 
-  EXPECT_TRUE(param3->Plus(&x[x_cursor],
-                           &delta[delta_cursor],
-                           &x_plus_delta[x_cursor]));
+  EXPECT_TRUE(param3->Plus(
+      &x[x_cursor], &delta[delta_cursor], &x_plus_delta[x_cursor]));
   x_cursor += param3->GlobalSize();
   delta_cursor += param3->LocalSize();
 
-  EXPECT_TRUE(param4->Plus(&x[x_cursor],
-                           &delta[delta_cursor],
-                           &x_plus_delta[x_cursor]));
+  EXPECT_TRUE(param4->Plus(
+      &x[x_cursor], &delta[delta_cursor], &x_plus_delta[x_cursor]));
   x_cursor += param4->GlobalSize();
   delta_cursor += param4->LocalSize();
 
@@ -725,45 +908,41 @@
     x[i] = RandNormal();
   }
 
-  Matrix jacobian = Matrix::Random(product_param.GlobalSize(),
-                                   product_param.LocalSize());
+  Matrix jacobian =
+      Matrix::Random(product_param.GlobalSize(), product_param.LocalSize());
   EXPECT_TRUE(product_param.ComputeJacobian(&x[0], jacobian.data()));
   int x_cursor = 0;
   int delta_cursor = 0;
 
   Matrix jacobian1(param1->GlobalSize(), param1->LocalSize());
   EXPECT_TRUE(param1->ComputeJacobian(&x[x_cursor], jacobian1.data()));
-  jacobian.block(x_cursor, delta_cursor,
-                 param1->GlobalSize(),
-                 param1->LocalSize())
-      -= jacobian1;
+  jacobian.block(
+      x_cursor, delta_cursor, param1->GlobalSize(), param1->LocalSize()) -=
+      jacobian1;
   x_cursor += param1->GlobalSize();
   delta_cursor += param1->LocalSize();
 
   Matrix jacobian2(param2->GlobalSize(), param2->LocalSize());
   EXPECT_TRUE(param2->ComputeJacobian(&x[x_cursor], jacobian2.data()));
-  jacobian.block(x_cursor, delta_cursor,
-                 param2->GlobalSize(),
-                 param2->LocalSize())
-      -= jacobian2;
+  jacobian.block(
+      x_cursor, delta_cursor, param2->GlobalSize(), param2->LocalSize()) -=
+      jacobian2;
   x_cursor += param2->GlobalSize();
   delta_cursor += param2->LocalSize();
 
   Matrix jacobian3(param3->GlobalSize(), param3->LocalSize());
   EXPECT_TRUE(param3->ComputeJacobian(&x[x_cursor], jacobian3.data()));
-  jacobian.block(x_cursor, delta_cursor,
-                 param3->GlobalSize(),
-                 param3->LocalSize())
-      -= jacobian3;
+  jacobian.block(
+      x_cursor, delta_cursor, param3->GlobalSize(), param3->LocalSize()) -=
+      jacobian3;
   x_cursor += param3->GlobalSize();
   delta_cursor += param3->LocalSize();
 
   Matrix jacobian4(param4->GlobalSize(), param4->LocalSize());
   EXPECT_TRUE(param4->ComputeJacobian(&x[x_cursor], jacobian4.data()));
-  jacobian.block(x_cursor, delta_cursor,
-                 param4->GlobalSize(),
-                 param4->LocalSize())
-      -= jacobian4;
+  jacobian.block(
+      x_cursor, delta_cursor, param4->GlobalSize(), param4->LocalSize()) -=
+      jacobian4;
   x_cursor += param4->GlobalSize();
   delta_cursor += param4->LocalSize();
 
diff --git a/internal/ceres/loss_function.cc b/internal/ceres/loss_function.cc
index bf41b9e..353f29a 100644
--- a/internal/ceres/loss_function.cc
+++ b/internal/ceres/loss_function.cc
@@ -52,7 +52,7 @@
     const double r = sqrt(s);
     rho[0] = 2.0 * a_ * r - b_;
     rho[1] = std::max(std::numeric_limits<double>::min(), a_ / r);
-    rho[2] = - rho[1] / (2.0 * s);
+    rho[2] = -rho[1] / (2.0 * s);
   } else {
     // Inlier region.
     rho[0] = s;
@@ -67,7 +67,7 @@
   // 'sum' and 'tmp' are always positive, assuming that 's' is.
   rho[0] = 2.0 * b_ * (tmp - 1.0);
   rho[1] = std::max(std::numeric_limits<double>::min(), 1.0 / tmp);
-  rho[2] = - (c_ * rho[1]) / (2.0 * sum);
+  rho[2] = -(c_ * rho[1]) / (2.0 * sum);
 }
 
 void CauchyLoss::Evaluate(double s, double rho[3]) const {
@@ -76,7 +76,7 @@
   // 'sum' and 'inv' are always positive, assuming that 's' is.
   rho[0] = b_ * log(sum);
   rho[1] = std::max(std::numeric_limits<double>::min(), inv);
-  rho[2] = - c_ * (inv * inv);
+  rho[2] = -c_ * (inv * inv);
 }
 
 void ArctanLoss::Evaluate(double s, double rho[3]) const {
@@ -89,9 +89,7 @@
 }
 
 TolerantLoss::TolerantLoss(double a, double b)
-    : a_(a),
-      b_(b),
-      c_(b * log(1.0 + exp(-a / b))) {
+    : a_(a), b_(b), c_(b * log(1.0 + exp(-a / b))) {
   CHECK_GE(a, 0.0);
   CHECK_GT(b, 0.0);
 }
@@ -102,7 +100,9 @@
   // large, it will overflow.  Since numerically 1 + e^x == e^x when the
   // x is greater than about ln(2^53) for doubles, beyond this threshold
   // we substitute x for ln(1 + e^x) as a numerically equivalent approximation.
-  static const double kLog2Pow53 = 36.7;  // ln(MathLimits<double>::kEpsilon).
+
+  // ln(MathLimits<double>::kEpsilon).
+  static constexpr double kLog2Pow53 = 36.7;
   if (x > kLog2Pow53) {
     rho[0] = s - a_ - c_;
     rho[1] = 1.0;
@@ -120,23 +120,22 @@
     // Inlier region.
     const double value = 1.0 - s / a_squared_;
     const double value_sq = value * value;
-    rho[0] = a_squared_ / 6.0 * (1.0 - value_sq * value);
-    rho[1] = 0.5 * value_sq;
-    rho[2] = -1.0 / a_squared_ * value;
+    rho[0] = a_squared_ / 3.0 * (1.0 - value_sq * value);
+    rho[1] = value_sq;
+    rho[2] = -2.0 / a_squared_ * value;
   } else {
     // Outlier region.
-    rho[0] = a_squared_ / 6.0;
+    rho[0] = a_squared_ / 3.0;
     rho[1] = 0.0;
     rho[2] = 0.0;
   }
 }
 
-ComposedLoss::ComposedLoss(const LossFunction* f, Ownership ownership_f,
-                           const LossFunction* g, Ownership ownership_g)
-    : f_(f),
-      g_(g),
-      ownership_f_(ownership_f),
-      ownership_g_(ownership_g) {
+ComposedLoss::ComposedLoss(const LossFunction* f,
+                           Ownership ownership_f,
+                           const LossFunction* g,
+                           Ownership ownership_g)
+    : f_(f), g_(g), ownership_f_(ownership_f), ownership_g_(ownership_g) {
   CHECK(f_ != nullptr);
   CHECK(g_ != nullptr);
 }
diff --git a/internal/ceres/loss_function_test.cc b/internal/ceres/loss_function_test.cc
index 406ace7..638c0c9 100644
--- a/internal/ceres/loss_function_test.cc
+++ b/internal/ceres/loss_function_test.cc
@@ -66,7 +66,7 @@
   ASSERT_NEAR(fd_1, rho[1], 1e-6);
 
   // Second derivative.
-  const double fd_2 = (fwd[0] - 2*rho[0] + bwd[0]) / (kH * kH);
+  const double fd_2 = (fwd[0] - 2 * rho[0] + bwd[0]) / (kH * kH);
   ASSERT_NEAR(fd_2, rho[2], 1e-6);
 }
 }  // namespace
@@ -81,6 +81,12 @@
 TEST(LossFunction, TrivialLoss) {
   AssertLossFunctionIsValid(TrivialLoss(), 0.357);
   AssertLossFunctionIsValid(TrivialLoss(), 1.792);
+  // Check that at s = 0: rho = [0, 1, 0].
+  double rho[3];
+  TrivialLoss().Evaluate(0.0, rho);
+  ASSERT_NEAR(rho[0], 0.0, 1e-6);
+  ASSERT_NEAR(rho[1], 1.0, 1e-6);
+  ASSERT_NEAR(rho[2], 0.0, 1e-6);
 }
 
 TEST(LossFunction, HuberLoss) {
@@ -88,6 +94,12 @@
   AssertLossFunctionIsValid(HuberLoss(0.7), 1.792);
   AssertLossFunctionIsValid(HuberLoss(1.3), 0.357);
   AssertLossFunctionIsValid(HuberLoss(1.3), 1.792);
+  // Check that at s = 0: rho = [0, 1, 0].
+  double rho[3];
+  HuberLoss(0.7).Evaluate(0.0, rho);
+  ASSERT_NEAR(rho[0], 0.0, 1e-6);
+  ASSERT_NEAR(rho[1], 1.0, 1e-6);
+  ASSERT_NEAR(rho[2], 0.0, 1e-6);
 }
 
 TEST(LossFunction, SoftLOneLoss) {
@@ -95,6 +107,12 @@
   AssertLossFunctionIsValid(SoftLOneLoss(0.7), 1.792);
   AssertLossFunctionIsValid(SoftLOneLoss(1.3), 0.357);
   AssertLossFunctionIsValid(SoftLOneLoss(1.3), 1.792);
+  // Check that at s = 0: rho = [0, 1, -1 / (2 * a^2)].
+  double rho[3];
+  SoftLOneLoss(0.7).Evaluate(0.0, rho);
+  ASSERT_NEAR(rho[0], 0.0, 1e-6);
+  ASSERT_NEAR(rho[1], 1.0, 1e-6);
+  ASSERT_NEAR(rho[2], -0.5 / (0.7 * 0.7), 1e-6);
 }
 
 TEST(LossFunction, CauchyLoss) {
@@ -102,6 +120,12 @@
   AssertLossFunctionIsValid(CauchyLoss(0.7), 1.792);
   AssertLossFunctionIsValid(CauchyLoss(1.3), 0.357);
   AssertLossFunctionIsValid(CauchyLoss(1.3), 1.792);
+  // Check that at s = 0: rho = [0, 1, -1 / a^2].
+  double rho[3];
+  CauchyLoss(0.7).Evaluate(0.0, rho);
+  ASSERT_NEAR(rho[0], 0.0, 1e-6);
+  ASSERT_NEAR(rho[1], 1.0, 1e-6);
+  ASSERT_NEAR(rho[2], -1.0 / (0.7 * 0.7), 1e-6);
 }
 
 TEST(LossFunction, ArctanLoss) {
@@ -109,6 +133,12 @@
   AssertLossFunctionIsValid(ArctanLoss(0.7), 1.792);
   AssertLossFunctionIsValid(ArctanLoss(1.3), 0.357);
   AssertLossFunctionIsValid(ArctanLoss(1.3), 1.792);
+  // Check that at s = 0: rho = [0, 1, 0].
+  double rho[3];
+  ArctanLoss(0.7).Evaluate(0.0, rho);
+  ASSERT_NEAR(rho[0], 0.0, 1e-6);
+  ASSERT_NEAR(rho[1], 1.0, 1e-6);
+  ASSERT_NEAR(rho[2], 0.0, 1e-6);
 }
 
 TEST(LossFunction, TolerantLoss) {
@@ -135,6 +165,12 @@
   AssertLossFunctionIsValid(TukeyLoss(0.7), 1.792);
   AssertLossFunctionIsValid(TukeyLoss(1.3), 0.357);
   AssertLossFunctionIsValid(TukeyLoss(1.3), 1.792);
+  // Check that at s = 0: rho = [0, 1, -2 / a^2].
+  double rho[3];
+  TukeyLoss(0.7).Evaluate(0.0, rho);
+  ASSERT_NEAR(rho[0], 0.0, 1e-6);
+  ASSERT_NEAR(rho[1], 1.0, 1e-6);
+  ASSERT_NEAR(rho[2], -2.0 / (0.7 * 0.7), 1e-6);
 }
 
 TEST(LossFunction, ComposedLoss) {
@@ -183,15 +219,16 @@
     AssertLossFunctionIsValid(scaled_loss, 1.792);
   }
   {
-    ScaledLoss scaled_loss(
-        new TolerantLoss(1.3, 0.1), 10, TAKE_OWNERSHIP);
+    ScaledLoss scaled_loss(new TolerantLoss(1.3, 0.1), 10, TAKE_OWNERSHIP);
     AssertLossFunctionIsValid(scaled_loss, 1.792);
   }
   {
-    ScaledLoss scaled_loss(
-        new ComposedLoss(
-            new HuberLoss(0.8), TAKE_OWNERSHIP,
-            new TolerantLoss(1.3, 0.5), TAKE_OWNERSHIP), 10, TAKE_OWNERSHIP);
+    ScaledLoss scaled_loss(new ComposedLoss(new HuberLoss(0.8),
+                                            TAKE_OWNERSHIP,
+                                            new TolerantLoss(1.3, 0.5),
+                                            TAKE_OWNERSHIP),
+                           10,
+                           TAKE_OWNERSHIP);
     AssertLossFunctionIsValid(scaled_loss, 1.792);
   }
 }
@@ -199,8 +236,7 @@
 TEST(LossFunction, LossFunctionWrapper) {
   // Initialization
   HuberLoss loss_function1(1.0);
-  LossFunctionWrapper loss_function_wrapper(new HuberLoss(1.0),
-                                            TAKE_OWNERSHIP);
+  LossFunctionWrapper loss_function_wrapper(new HuberLoss(1.0), TAKE_OWNERSHIP);
 
   double s = 0.862;
   double rho_gold[3];
@@ -245,7 +281,6 @@
   for (int i = 0; i < 3; ++i) {
     EXPECT_NEAR(rho[i], rho_gold[i], 1e-12);
   }
-
 }
 
 }  // namespace internal
diff --git a/internal/ceres/low_rank_inverse_hessian.cc b/internal/ceres/low_rank_inverse_hessian.cc
index f3953c4..c73e5db 100644
--- a/internal/ceres/low_rank_inverse_hessian.cc
+++ b/internal/ceres/low_rank_inverse_hessian.cc
@@ -28,10 +28,11 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/low_rank_inverse_hessian.h"
+
 #include <list>
 
 #include "ceres/internal/eigen.h"
-#include "ceres/low_rank_inverse_hessian.h"
 #include "glog/logging.h"
 
 namespace ceres {
@@ -84,8 +85,7 @@
       approximate_eigenvalue_scale_(1.0),
       delta_x_history_(num_parameters, max_num_corrections),
       delta_gradient_history_(num_parameters, max_num_corrections),
-      delta_x_dot_delta_gradient_(max_num_corrections) {
-}
+      delta_x_dot_delta_gradient_(max_num_corrections) {}
 
 bool LowRankInverseHessian::Update(const Vector& delta_x,
                                    const Vector& delta_gradient) {
@@ -93,13 +93,12 @@
   if (delta_x_dot_delta_gradient <=
       kLBFGSSecantConditionHessianUpdateTolerance) {
     VLOG(2) << "Skipping L-BFGS Update, delta_x_dot_delta_gradient too "
-            << "small: " << delta_x_dot_delta_gradient << ", tolerance: "
-            << kLBFGSSecantConditionHessianUpdateTolerance
+            << "small: " << delta_x_dot_delta_gradient
+            << ", tolerance: " << kLBFGSSecantConditionHessianUpdateTolerance
             << " (Secant condition).";
     return false;
   }
 
-
   int next = indices_.size();
   // Once the size of the list reaches max_num_corrections_, simulate
   // a circular buffer by removing the first element of the list and
@@ -132,7 +131,7 @@
        it != indices_.rend();
        ++it) {
     const double alpha_i = delta_x_history_.col(*it).dot(search_direction) /
-        delta_x_dot_delta_gradient_(*it);
+                           delta_x_dot_delta_gradient_(*it);
     search_direction -= alpha_i * delta_gradient_history_.col(*it);
     alpha(*it) = alpha_i;
   }
@@ -177,7 +176,7 @@
 
   for (const int i : indices_) {
     const double beta = delta_gradient_history_.col(i).dot(search_direction) /
-        delta_x_dot_delta_gradient_(i);
+                        delta_x_dot_delta_gradient_(i);
     search_direction += delta_x_history_.col(i) * (alpha(i) - beta);
   }
 }
diff --git a/internal/ceres/low_rank_inverse_hessian.h b/internal/ceres/low_rank_inverse_hessian.h
index 2c768c2..0028a98 100644
--- a/internal/ceres/low_rank_inverse_hessian.h
+++ b/internal/ceres/low_rank_inverse_hessian.h
@@ -54,7 +54,7 @@
 // enhanced with scaling rule by Byrd, Nocedal and Schanbel.
 //
 // Nocedal, J. (1980). "Updating Quasi-Newton Matrices with Limited
-// Storage". Mathematics of Computation 35 (151): 773–782.
+// Storage". Mathematics of Computation 35 (151): 773-782.
 //
 // Byrd, R. H.; Nocedal, J.; Schnabel, R. B. (1994).
 // "Representations of Quasi-Newton Matrices and their use in
@@ -84,12 +84,12 @@
   bool Update(const Vector& delta_x, const Vector& delta_gradient);
 
   // LinearOperator interface
-  virtual void RightMultiply(const double* x, double* y) const;
-  virtual void LeftMultiply(const double* x, double* y) const {
+  void RightMultiply(const double* x, double* y) const final;
+  void LeftMultiply(const double* x, double* y) const final {
     RightMultiply(x, y);
   }
-  virtual int num_rows() const { return num_parameters_; }
-  virtual int num_cols() const { return num_parameters_; }
+  int num_rows() const final { return num_parameters_; }
+  int num_cols() const final { return num_parameters_; }
 
  private:
   const int num_parameters_;
diff --git a/internal/ceres/map_util.h b/internal/ceres/map_util.h
index f55aee3..6e310f8 100644
--- a/internal/ceres/map_util.h
+++ b/internal/ceres/map_util.h
@@ -34,6 +34,7 @@
 #define CERES_INTERNAL_MAP_UTIL_H_
 
 #include <utility>
+
 #include "ceres/internal/port.h"
 #include "glog/logging.h"
 
@@ -55,9 +56,9 @@
 // This version assumes the key is printable, and includes it in the fatal log
 // message.
 template <class Collection>
-const typename Collection::value_type::second_type&
-FindOrDie(const Collection& collection,
-          const typename Collection::value_type::first_type& key) {
+const typename Collection::value_type::second_type& FindOrDie(
+    const Collection& collection,
+    const typename Collection::value_type::first_type& key) {
   typename Collection::const_iterator it = collection.find(key);
   CHECK(it != collection.end()) << "Map key not found: " << key;
   return it->second;
@@ -67,10 +68,10 @@
 // If the key is present in the map then the value associated with that
 // key is returned, otherwise the value passed as a default is returned.
 template <class Collection>
-const typename Collection::value_type::second_type
-FindWithDefault(const Collection& collection,
-                const typename Collection::value_type::first_type& key,
-                const typename Collection::value_type::second_type& value) {
+const typename Collection::value_type::second_type FindWithDefault(
+    const Collection& collection,
+    const typename Collection::value_type::first_type& key,
+    const typename Collection::value_type::second_type& value) {
   typename Collection::const_iterator it = collection.find(key);
   if (it == collection.end()) {
     return value;
@@ -84,7 +85,7 @@
 // took place, false indicates the key was already present.
 template <class Collection>
 bool InsertIfNotPresent(
-    Collection * const collection,
+    Collection* const collection,
     const typename Collection::value_type::first_type& key,
     const typename Collection::value_type::second_type& value) {
   std::pair<typename Collection::iterator, bool> ret =
@@ -96,9 +97,9 @@
 // Same as above but the returned pointer is not const and can be used to change
 // the stored value.
 template <class Collection>
-typename Collection::value_type::second_type*
-FindOrNull(Collection& collection,  // NOLINT
-           const typename Collection::value_type::first_type& key) {
+typename Collection::value_type::second_type* FindOrNull(
+    Collection& collection,  // NOLINT
+    const typename Collection::value_type::first_type& key) {
   typename Collection::iterator it = collection.find(key);
   if (it == collection.end()) {
     return 0;
@@ -116,13 +117,13 @@
 
 // Inserts a new key/value into a map or hash_map.
 // Dies if the key is already present.
-template<class Collection>
+template <class Collection>
 void InsertOrDie(Collection* const collection,
                  const typename Collection::value_type::first_type& key,
                  const typename Collection::value_type::second_type& data) {
   typedef typename Collection::value_type value_type;
   CHECK(collection->insert(value_type(key, data)).second)
-    << "duplicate key: " << key;
+      << "duplicate key: " << key;
 }
 
 }  // namespace ceres
diff --git a/internal/ceres/miniglog/glog/logging.cc b/internal/ceres/miniglog/glog/logging.cc
index 372ecb0..0863f61 100644
--- a/internal/ceres/miniglog/glog/logging.cc
+++ b/internal/ceres/miniglog/glog/logging.cc
@@ -34,6 +34,6 @@
 
 // This is the set of log sinks. This must be in a separate library to ensure
 // that there is only one instance of this across the entire program.
-std::set<google::LogSink *> log_sinks_global;
+std::set<google::LogSink*> log_sinks_global;
 
-}  // namespace ceres
+}  // namespace google
diff --git a/internal/ceres/miniglog/glog/logging.h b/internal/ceres/miniglog/glog/logging.h
index 0fdf382..98d2b68 100644
--- a/internal/ceres/miniglog/glog/logging.h
+++ b/internal/ceres/miniglog/glog/logging.h
@@ -93,7 +93,7 @@
 #define CERCES_INTERNAL_MINIGLOG_GLOG_LOGGING_H_
 
 #ifdef ANDROID
-#  include <android/log.h>
+#include <android/log.h>
 #endif  // ANDROID
 
 #include <algorithm>
@@ -106,24 +106,31 @@
 #include <vector>
 
 // For appropriate definition of CERES_EXPORT macro.
+// clang-format off
 #include "ceres/internal/port.h"
+// clang-format on
+
 #include "ceres/internal/disable_warnings.h"
 
 // Log severity level constants.
+// clang-format off
 const int FATAL   = -3;
 const int ERROR   = -2;
 const int WARNING = -1;
 const int INFO    =  0;
+// clang-format on
 
 // ------------------------- Glog compatibility ------------------------------
 
 namespace google {
 
 typedef int LogSeverity;
+// clang-format off
 const int INFO    = ::INFO;
 const int WARNING = ::WARNING;
 const int ERROR   = ::ERROR;
 const int FATAL   = ::FATAL;
+// clang-format on
 
 // Sink class used for integration with mock and test functions. If sinks are
 // added, all log output is also sent to each sink through the send function.
@@ -143,20 +150,18 @@
 };
 
 // Global set of log sinks. The actual object is defined in logging.cc.
-extern CERES_EXPORT std::set<LogSink *> log_sinks_global;
+extern CERES_EXPORT std::set<LogSink*> log_sinks_global;
 
-inline void InitGoogleLogging(char *argv) {
+inline void InitGoogleLogging(char* argv) {
   // Do nothing; this is ignored.
 }
 
 // Note: the Log sink functions are not thread safe.
-inline void AddLogSink(LogSink *sink) {
+inline void AddLogSink(LogSink* sink) {
   // TODO(settinger): Add locks for thread safety.
   log_sinks_global.insert(sink);
 }
-inline void RemoveLogSink(LogSink *sink) {
-  log_sinks_global.erase(sink);
-}
+inline void RemoveLogSink(LogSink* sink) { log_sinks_global.erase(sink); }
 
 }  // namespace google
 
@@ -170,8 +175,8 @@
 // use of the log macros LG, LOG, or VLOG.
 class CERES_EXPORT MessageLogger {
  public:
-  MessageLogger(const char *file, int line, const char *tag, int severity)
-    : file_(file), line_(line), tag_(tag), severity_(severity) {
+  MessageLogger(const char* file, int line, const char* tag, int severity)
+      : file_(file), line_(line), tag_(tag), severity_(severity) {
     // Pre-pend the stream with the file and line number.
     StripBasename(std::string(file), &filename_only_);
     stream_ << filename_only_ << ":" << line << " ";
@@ -193,8 +198,8 @@
 
     // Bound the logging level.
     const int kMaxVerboseLevel = 2;
-    int android_level_index = std::min(std::max(FATAL, severity_),
-                                       kMaxVerboseLevel) - FATAL;
+    int android_level_index =
+        std::min(std::max(FATAL, severity_), kMaxVerboseLevel) - FATAL;
     int android_log_level = android_log_levels[android_level_index];
 
     // Output the log string the Android log at the appropriate level.
@@ -202,9 +207,7 @@
 
     // Indicate termination if needed.
     if (severity_ == FATAL) {
-      __android_log_write(ANDROID_LOG_FATAL,
-                          tag_.c_str(),
-                          "terminating.\n");
+      __android_log_write(ANDROID_LOG_FATAL, tag_.c_str(), "terminating.\n");
     }
 #else
     // If not building on Android, log all output to std::cerr.
@@ -222,12 +225,12 @@
   }
 
   // Return the stream associated with the logger object.
-  std::stringstream &stream() { return stream_; }
+  std::stringstream& stream() { return stream_; }
 
  private:
   void LogToSinks(int severity) {
     time_t rawtime;
-    time (&rawtime);
+    time(&rawtime);
 
     struct tm timeinfo;
 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
@@ -241,24 +244,31 @@
     std::set<google::LogSink*>::iterator iter;
     // Send the log message to all sinks.
     for (iter = google::log_sinks_global.begin();
-         iter != google::log_sinks_global.end(); ++iter) {
-      (*iter)->send(severity, file_.c_str(), filename_only_.c_str(), line_,
-                    &timeinfo, stream_.str().c_str(), stream_.str().size());
+         iter != google::log_sinks_global.end();
+         ++iter) {
+      (*iter)->send(severity,
+                    file_.c_str(),
+                    filename_only_.c_str(),
+                    line_,
+                    &timeinfo,
+                    stream_.str().c_str(),
+                    stream_.str().size());
     }
   }
 
   void WaitForSinks() {
     // TODO(settinger): Add locks for thread safety.
-    std::set<google::LogSink *>::iterator iter;
+    std::set<google::LogSink*>::iterator iter;
 
     // Call WaitTillSent() for all sinks.
     for (iter = google::log_sinks_global.begin();
-         iter != google::log_sinks_global.end(); ++iter) {
+         iter != google::log_sinks_global.end();
+         ++iter) {
       (*iter)->WaitTillSent();
     }
   }
 
-  void StripBasename(const std::string &full_path, std::string *filename) {
+  void StripBasename(const std::string& full_path, std::string* filename) {
     // TODO(settinger): Add support for OSs with different path separators.
     const char kSeparator = '/';
     size_t pos = full_path.rfind(kSeparator);
@@ -284,16 +294,18 @@
 // is not used" and "statement has no effect".
 class CERES_EXPORT LoggerVoidify {
  public:
-  LoggerVoidify() { }
+  LoggerVoidify() {}
   // This has to be an operator with a precedence lower than << but
   // higher than ?:
-  void operator&(const std::ostream &s) { }
+  void operator&(const std::ostream& s) {}
 };
 
 // Log only if condition is met.  Otherwise evaluates to void.
+// clang-format off
 #define LOG_IF(severity, condition) \
     !(condition) ? (void) 0 : LoggerVoidify() & \
       MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream()
+// clang-format on
 
 // Log only if condition is NOT met.  Otherwise evaluates to void.
 #define LOG_IF_FALSE(severity, condition) LOG_IF(severity, !(condition))
@@ -301,6 +313,7 @@
 // LG is a convenient shortcut for LOG(INFO). Its use is in new
 // google3 code is discouraged and the following shortcut exists for
 // backward compatibility with existing code.
+// clang-format off
 #ifdef MAX_LOG_LEVEL
 #  define LOG(n)  LOG_IF(n, n <= MAX_LOG_LEVEL)
 #  define VLOG(n) LOG_IF(n, n <= MAX_LOG_LEVEL)
@@ -326,37 +339,39 @@
 #  define DLOG(severity) true ? (void) 0 : LoggerVoidify() & \
       MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream()
 #endif
-
+// clang-format on
 
 // Log a message and terminate.
-template<class T>
-void LogMessageFatal(const char *file, int line, const T &message) {
-  MessageLogger((char *)__FILE__, __LINE__, "native", FATAL).stream()
-      << message;
+template <class T>
+void LogMessageFatal(const char* file, int line, const T& message) {
+  MessageLogger((char*)__FILE__, __LINE__, "native", FATAL).stream() << message;
 }
 
 // ---------------------------- CHECK macros ---------------------------------
 
 // Check for a given boolean condition.
-#define CHECK(condition) LOG_IF_FALSE(FATAL, condition) \
-        << "Check failed: " #condition " "
+#define CHECK(condition) \
+  LOG_IF_FALSE(FATAL, condition) << "Check failed: " #condition " "
 
 #ifndef NDEBUG
 // Debug only version of CHECK
-#  define DCHECK(condition) LOG_IF_FALSE(FATAL, condition) \
-          << "Check failed: " #condition " "
+#define DCHECK(condition) \
+  LOG_IF_FALSE(FATAL, condition) << "Check failed: " #condition " "
 #else
 // Optimized version - generates no code.
-#  define DCHECK(condition) if (false) LOG_IF_FALSE(FATAL, condition) \
-          << "Check failed: " #condition " "
+#define DCHECK(condition) \
+  if (false) LOG_IF_FALSE(FATAL, condition) << "Check failed: " #condition " "
 #endif  // NDEBUG
 
 // ------------------------- CHECK_OP macros ---------------------------------
 
 // Generic binary operator check macro. This should not be directly invoked,
 // instead use the binary comparison macros defined below.
-#define CHECK_OP(val1, val2, op) LOG_IF_FALSE(FATAL, ((val1) op (val2))) \
-  << "Check failed: " #val1 " " #op " " #val2 " "
+#define CHECK_OP(val1, val2, op)        \
+  LOG_IF_FALSE(FATAL, ((val1)op(val2))) \
+      << "Check failed: " #val1 " " #op " " #val2 " "
+
+// clang-format off
 
 // Check_op macro definitions
 #define CHECK_EQ(val1, val2) CHECK_OP(val1, val2, ==)
@@ -384,12 +399,14 @@
 #  define DCHECK_GT(val1, val2) if (false) CHECK_OP(val1, val2, >)
 #endif  // NDEBUG
 
+// clang-format on
+
 // ---------------------------CHECK_NOTNULL macros ---------------------------
 
 // Helpers for CHECK_NOTNULL(). Two are necessary to support both raw pointers
 // and smart pointers.
 template <typename T>
-T& CheckNotNullCommon(const char *file, int line, const char *names, T& t) {
+T& CheckNotNullCommon(const char* file, int line, const char* names, T& t) {
   if (t == NULL) {
     LogMessageFatal(file, line, std::string(names));
   }
@@ -397,12 +414,12 @@
 }
 
 template <typename T>
-T* CheckNotNull(const char *file, int line, const char *names, T* t) {
+T* CheckNotNull(const char* file, int line, const char* names, T* t) {
   return CheckNotNullCommon(file, line, names, t);
 }
 
 template <typename T>
-T& CheckNotNull(const char *file, int line, const char *names, T& t) {
+T& CheckNotNull(const char* file, int line, const char* names, T& t) {
   return CheckNotNullCommon(file, line, names, t);
 }
 
@@ -416,7 +433,8 @@
   CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))
 #else
 // Optimized version - generates no code.
-#define DCHECK_NOTNULL(val) if (false)\
+#define DCHECK_NOTNULL(val) \
+  if (false)                \
   CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))
 #endif  // NDEBUG
 
diff --git a/internal/ceres/minimizer.cc b/internal/ceres/minimizer.cc
index f596033..b96e0c9 100644
--- a/internal/ceres/minimizer.cc
+++ b/internal/ceres/minimizer.cc
@@ -28,8 +28,9 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
-#include "ceres/line_search_minimizer.h"
 #include "ceres/minimizer.h"
+
+#include "ceres/line_search_minimizer.h"
 #include "ceres/trust_region_minimizer.h"
 #include "ceres/types.h"
 #include "glog/logging.h"
@@ -50,7 +51,6 @@
   return NULL;
 }
 
-
 Minimizer::~Minimizer() {}
 
 bool Minimizer::RunCallbacks(const Minimizer::Options& options,
@@ -70,12 +70,16 @@
       summary->termination_type = USER_SUCCESS;
       summary->message =
           "User callback returned SOLVER_TERMINATE_SUCCESSFULLY.";
-      VLOG_IF(1, is_not_silent) << "Terminating: " << summary->message;
+      if (is_not_silent) {
+        VLOG(1) << "Terminating: " << summary->message;
+      }
       return false;
     case SOLVER_ABORT:
       summary->termination_type = USER_FAILURE;
       summary->message = "User callback returned SOLVER_ABORT.";
-      VLOG_IF(1, is_not_silent) << "Terminating: " << summary->message;
+      if (is_not_silent) {
+        VLOG(1) << "Terminating: " << summary->message;
+      }
       return false;
     default:
       LOG(FATAL) << "Unknown type of user callback status";
diff --git a/internal/ceres/minimizer.h b/internal/ceres/minimizer.h
index afdd60d..246550d 100644
--- a/internal/ceres/minimizer.h
+++ b/internal/ceres/minimizer.h
@@ -34,6 +34,7 @@
 #include <memory>
 #include <string>
 #include <vector>
+
 #include "ceres/internal/port.h"
 #include "ceres/iteration_callback.h"
 #include "ceres/solver.h"
@@ -48,19 +49,15 @@
 class LinearSolver;
 
 // Interface for non-linear least squares solvers.
-class Minimizer {
+class CERES_EXPORT_INTERNAL Minimizer {
  public:
   // Options struct to control the behaviour of the Minimizer. Please
   // see solver.h for detailed information about the meaning and
   // default values of each of these parameters.
   struct Options {
-    Options() {
-      Init(Solver::Options());
-    }
+    Options() { Init(Solver::Options()); }
 
-    explicit Options(const Solver::Options& options) {
-      Init(options);
-    }
+    explicit Options(const Solver::Options& options) { Init(options); }
 
     void Init(const Solver::Options& options) {
       num_threads = options.num_threads;
@@ -92,8 +89,7 @@
       max_lbfgs_rank = options.max_lbfgs_rank;
       use_approximate_eigenvalue_bfgs_scaling =
           options.use_approximate_eigenvalue_bfgs_scaling;
-      line_search_interpolation_type =
-          options.line_search_interpolation_type;
+      line_search_interpolation_type = options.line_search_interpolation_type;
       min_line_search_step_size = options.min_line_search_step_size;
       line_search_sufficient_function_decrease =
           options.line_search_sufficient_function_decrease;
@@ -107,8 +103,7 @@
           options.max_num_line_search_direction_restarts;
       line_search_sufficient_curvature_decrease =
           options.line_search_sufficient_curvature_decrease;
-      max_line_search_step_expansion =
-          options.max_line_search_step_expansion;
+      max_line_search_step_expansion = options.max_line_search_step_expansion;
       inner_iteration_tolerance = options.inner_iteration_tolerance;
       is_silent = (options.logging_type == SILENT);
       is_constrained = false;
diff --git a/internal/ceres/minimizer_test.cc b/internal/ceres/minimizer_test.cc
index fe9b15e..3de4abe 100644
--- a/internal/ceres/minimizer_test.cc
+++ b/internal/ceres/minimizer_test.cc
@@ -28,10 +28,11 @@
 //
 // Author: keir@google.com (Keir Mierle)
 
-#include "gtest/gtest.h"
-#include "ceres/iteration_callback.h"
 #include "ceres/minimizer.h"
+
+#include "ceres/iteration_callback.h"
 #include "ceres/solver.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
@@ -39,7 +40,7 @@
 class FakeIterationCallback : public IterationCallback {
  public:
   virtual ~FakeIterationCallback() {}
-  virtual CallbackReturnType operator()(const IterationSummary& summary) {
+  CallbackReturnType operator()(const IterationSummary& summary) final {
     return SOLVER_CONTINUE;
   }
 };
@@ -62,7 +63,7 @@
 class AbortingIterationCallback : public IterationCallback {
  public:
   virtual ~AbortingIterationCallback() {}
-  virtual CallbackReturnType operator()(const IterationSummary& summary) {
+  CallbackReturnType operator()(const IterationSummary& summary) final {
     return SOLVER_ABORT;
   }
 };
@@ -80,7 +81,7 @@
 class SucceedingIterationCallback : public IterationCallback {
  public:
   virtual ~SucceedingIterationCallback() {}
-  virtual CallbackReturnType operator()(const IterationSummary& summary) {
+  CallbackReturnType operator()(const IterationSummary& summary) final {
     return SOLVER_TERMINATE_SUCCESSFULLY;
   }
 };
diff --git a/internal/ceres/normal_prior.cc b/internal/ceres/normal_prior.cc
index a3d5d8e..4a62132 100644
--- a/internal/ceres/normal_prior.cc
+++ b/internal/ceres/normal_prior.cc
@@ -32,14 +32,14 @@
 
 #include <cstddef>
 #include <vector>
+
 #include "ceres/internal/eigen.h"
 #include "ceres/types.h"
 #include "glog/logging.h"
 
 namespace ceres {
 
-NormalPrior::NormalPrior(const Matrix& A, const Vector& b)
-    : A_(A), b_(b) {
+NormalPrior::NormalPrior(const Matrix& A, const Vector& b) : A_(A), b_(b) {
   CHECK_GT(b_.rows(), 0);
   CHECK_GT(A_.rows(), 0);
   CHECK_EQ(b_.rows(), A.cols());
diff --git a/internal/ceres/normal_prior_test.cc b/internal/ceres/normal_prior_test.cc
index 1a51cfd..518c18e 100644
--- a/internal/ceres/normal_prior_test.cc
+++ b/internal/ceres/normal_prior_test.cc
@@ -32,16 +32,17 @@
 
 #include <cstddef>
 
-#include "gtest/gtest.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/random.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
 
+namespace {
+
 void RandomVector(Vector* v) {
-  for (int r = 0; r < v->rows(); ++r)
-    (*v)[r] = 2 * RandDouble() - 1;
+  for (int r = 0; r < v->rows(); ++r) (*v)[r] = 2 * RandDouble() - 1;
 }
 
 void RandomMatrix(Matrix* m) {
@@ -52,6 +53,8 @@
   }
 }
 
+}  // namespace
+
 TEST(NormalPriorTest, ResidualAtRandomPosition) {
   srand(5);
 
@@ -63,11 +66,10 @@
       Matrix A(num_rows, num_cols);
       RandomMatrix(&A);
 
-      double * x = new double[num_cols];
-      for (int i = 0; i < num_cols; ++i)
-        x[i] = 2 * RandDouble() - 1;
+      double* x = new double[num_cols];
+      for (int i = 0; i < num_cols; ++i) x[i] = 2 * RandDouble() - 1;
 
-      double * jacobian = new double[num_rows * num_cols];
+      double* jacobian = new double[num_rows * num_cols];
       Vector residuals(num_rows);
 
       NormalPrior prior(A, b);
@@ -83,8 +85,8 @@
       double jacobian_diff_norm = (J - A).norm();
       EXPECT_NEAR(jacobian_diff_norm, 0.0, 1e-10);
 
-      delete []x;
-      delete []jacobian;
+      delete[] x;
+      delete[] jacobian;
     }
   }
 }
@@ -100,9 +102,8 @@
       Matrix A(num_rows, num_cols);
       RandomMatrix(&A);
 
-      double * x = new double[num_cols];
-      for (int i = 0; i < num_cols; ++i)
-        x[i] = 2 * RandDouble() - 1;
+      double* x = new double[num_cols];
+      for (int i = 0; i < num_cols; ++i) x[i] = 2 * RandDouble() - 1;
 
       double* jacobians[1];
       jacobians[0] = NULL;
@@ -123,8 +124,7 @@
           (residuals - A * (VectorRef(x, num_cols) - b)).squaredNorm();
       EXPECT_NEAR(residual_diff_norm, 0, 1e-10);
 
-
-      delete []x;
+      delete[] x;
     }
   }
 }
diff --git a/internal/ceres/numeric_diff_cost_function_test.cc b/internal/ceres/numeric_diff_cost_function_test.cc
index 105bef5..a5f7a15 100644
--- a/internal/ceres/numeric_diff_cost_function_test.cc
+++ b/internal/ceres/numeric_diff_cost_function_test.cc
@@ -50,39 +50,36 @@
 
 TEST(NumericDiffCostFunction, EasyCaseFunctorCentralDifferences) {
   std::unique_ptr<CostFunction> cost_function;
-  cost_function.reset(
-      new NumericDiffCostFunction<EasyFunctor,
-                                  CENTRAL,
-                                  3,  /* number of residuals */
-                                  5,  /* size of x1 */
-                                  5   /* size of x2 */>(
-          new EasyFunctor));
+  cost_function.reset(new NumericDiffCostFunction<EasyFunctor,
+                                                  CENTRAL,
+                                                  3,  // number of residuals
+                                                  5,  // size of x1
+                                                  5   // size of x2
+                                                  >(new EasyFunctor));
   EasyFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, CENTRAL);
 }
 
 TEST(NumericDiffCostFunction, EasyCaseFunctorForwardDifferences) {
   std::unique_ptr<CostFunction> cost_function;
-  cost_function.reset(
-      new NumericDiffCostFunction<EasyFunctor,
-                                  FORWARD,
-                                  3,  /* number of residuals */
-                                  5,  /* size of x1 */
-                                  5   /* size of x2 */>(
-          new EasyFunctor));
+  cost_function.reset(new NumericDiffCostFunction<EasyFunctor,
+                                                  FORWARD,
+                                                  3,  // number of residuals
+                                                  5,  // size of x1
+                                                  5   // size of x2
+                                                  >(new EasyFunctor));
   EasyFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, FORWARD);
 }
 
 TEST(NumericDiffCostFunction, EasyCaseFunctorRidders) {
   std::unique_ptr<CostFunction> cost_function;
-  cost_function.reset(
-      new NumericDiffCostFunction<EasyFunctor,
-                                  RIDDERS,
-                                  3,  /* number of residuals */
-                                  5,  /* size of x1 */
-                                  5   /* size of x2 */>(
-          new EasyFunctor));
+  cost_function.reset(new NumericDiffCostFunction<EasyFunctor,
+                                                  RIDDERS,
+                                                  3,  // number of residuals
+                                                  5,  // size of x1
+                                                  5   // size of x2
+                                                  >(new EasyFunctor));
   EasyFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, RIDDERS);
 }
@@ -92,10 +89,10 @@
   cost_function.reset(
       new NumericDiffCostFunction<EasyCostFunction,
                                   CENTRAL,
-                                  3,  /* number of residuals */
-                                  5,  /* size of x1 */
-                                  5   /* size of x2 */>(
-          new EasyCostFunction, TAKE_OWNERSHIP));
+                                  3,  // number of residuals
+                                  5,  // size of x1
+                                  5   // size of x2
+                                  >(new EasyCostFunction, TAKE_OWNERSHIP));
   EasyFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, CENTRAL);
 }
@@ -105,10 +102,10 @@
   cost_function.reset(
       new NumericDiffCostFunction<EasyCostFunction,
                                   FORWARD,
-                                  3,  /* number of residuals */
-                                  5,  /* size of x1 */
-                                  5   /* size of x2 */>(
-          new EasyCostFunction, TAKE_OWNERSHIP));
+                                  3,  // number of residuals
+                                  5,  // size of x1
+                                  5   // size of x2
+                                  >(new EasyCostFunction, TAKE_OWNERSHIP));
   EasyFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, FORWARD);
 }
@@ -118,44 +115,39 @@
   cost_function.reset(
       new NumericDiffCostFunction<EasyCostFunction,
                                   RIDDERS,
-                                  3,  /* number of residuals */
-                                  5,  /* size of x1 */
-                                  5   /* size of x2 */>(
-          new EasyCostFunction, TAKE_OWNERSHIP));
+                                  3,  // number of residuals
+                                  5,  // size of x1
+                                  5   // size of x2
+                                  >(new EasyCostFunction, TAKE_OWNERSHIP));
   EasyFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, RIDDERS);
 }
 
-TEST(NumericDiffCostFunction,
-     TranscendentalCaseFunctorCentralDifferences) {
+TEST(NumericDiffCostFunction, TranscendentalCaseFunctorCentralDifferences) {
   std::unique_ptr<CostFunction> cost_function;
-  cost_function.reset(
-      new NumericDiffCostFunction<TranscendentalFunctor,
-                                  CENTRAL,
-                                  2,  /* number of residuals */
-                                  5,  /* size of x1 */
-                                  5   /* size of x2 */>(
-          new TranscendentalFunctor));
+  cost_function.reset(new NumericDiffCostFunction<TranscendentalFunctor,
+                                                  CENTRAL,
+                                                  2,  // number of residuals
+                                                  5,  // size of x1
+                                                  5   // size of x2
+                                                  >(new TranscendentalFunctor));
   TranscendentalFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, CENTRAL);
 }
 
-TEST(NumericDiffCostFunction,
-     TranscendentalCaseFunctorForwardDifferences) {
+TEST(NumericDiffCostFunction, TranscendentalCaseFunctorForwardDifferences) {
   std::unique_ptr<CostFunction> cost_function;
-  cost_function.reset(
-      new NumericDiffCostFunction<TranscendentalFunctor,
-                                  FORWARD,
-                                  2,  /* number of residuals */
-                                  5,  /* size of x1 */
-                                  5   /* size of x2 */>(
-          new TranscendentalFunctor));
+  cost_function.reset(new NumericDiffCostFunction<TranscendentalFunctor,
+                                                  FORWARD,
+                                                  2,  // number of residuals
+                                                  5,  // size of x1
+                                                  5   // size of x2
+                                                  >(new TranscendentalFunctor));
   TranscendentalFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, FORWARD);
 }
 
-TEST(NumericDiffCostFunction,
-     TranscendentalCaseFunctorRidders) {
+TEST(NumericDiffCostFunction, TranscendentalCaseFunctorRidders) {
   NumericDiffOptions options;
 
   // Using a smaller initial step size to overcome oscillatory function
@@ -163,13 +155,13 @@
   options.ridders_relative_initial_step_size = 1e-3;
 
   std::unique_ptr<CostFunction> cost_function;
-  cost_function.reset(
-      new NumericDiffCostFunction<TranscendentalFunctor,
-                                  RIDDERS,
-                                  2,  /* number of residuals */
-                                  5,  /* size of x1 */
-                                  5   /* size of x2 */>(
-          new TranscendentalFunctor, TAKE_OWNERSHIP, 2, options));
+  cost_function.reset(new NumericDiffCostFunction<TranscendentalFunctor,
+                                                  RIDDERS,
+                                                  2,  // number of residuals
+                                                  5,  // size of x1
+                                                  5   // size of x2
+                                                  >(
+      new TranscendentalFunctor, TAKE_OWNERSHIP, 2, options));
   TranscendentalFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, RIDDERS);
 }
@@ -177,13 +169,13 @@
 TEST(NumericDiffCostFunction,
      TranscendentalCaseCostFunctionCentralDifferences) {
   std::unique_ptr<CostFunction> cost_function;
-  cost_function.reset(
-      new NumericDiffCostFunction<TranscendentalCostFunction,
-                                  CENTRAL,
-                                  2,  /* number of residuals */
-                                  5,  /* size of x1 */
-                                  5   /* size of x2 */>(
-          new TranscendentalCostFunction, TAKE_OWNERSHIP));
+  cost_function.reset(new NumericDiffCostFunction<TranscendentalCostFunction,
+                                                  CENTRAL,
+                                                  2,  // number of residuals
+                                                  5,  // size of x1
+                                                  5   // size of x2
+                                                  >(
+      new TranscendentalCostFunction, TAKE_OWNERSHIP));
   TranscendentalFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, CENTRAL);
 }
@@ -191,19 +183,18 @@
 TEST(NumericDiffCostFunction,
      TranscendentalCaseCostFunctionForwardDifferences) {
   std::unique_ptr<CostFunction> cost_function;
-  cost_function.reset(
-      new NumericDiffCostFunction<TranscendentalCostFunction,
-                                  FORWARD,
-                                  2,  /* number of residuals */
-                                  5,  /* size of x1 */
-                                  5   /* size of x2 */>(
-          new TranscendentalCostFunction, TAKE_OWNERSHIP));
+  cost_function.reset(new NumericDiffCostFunction<TranscendentalCostFunction,
+                                                  FORWARD,
+                                                  2,  // number of residuals
+                                                  5,  // size of x1
+                                                  5   // size of x2
+                                                  >(
+      new TranscendentalCostFunction, TAKE_OWNERSHIP));
   TranscendentalFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, FORWARD);
 }
 
-TEST(NumericDiffCostFunction,
-     TranscendentalCaseCostFunctionRidders) {
+TEST(NumericDiffCostFunction, TranscendentalCaseCostFunctionRidders) {
   NumericDiffOptions options;
 
   // Using a smaller initial step size to overcome oscillatory function
@@ -211,23 +202,23 @@
   options.ridders_relative_initial_step_size = 1e-3;
 
   std::unique_ptr<CostFunction> cost_function;
-  cost_function.reset(
-      new NumericDiffCostFunction<TranscendentalCostFunction,
-                                  RIDDERS,
-                                  2,  /* number of residuals */
-                                  5,  /* size of x1 */
-                                  5   /* size of x2 */>(
-          new TranscendentalCostFunction, TAKE_OWNERSHIP, 2, options));
+  cost_function.reset(new NumericDiffCostFunction<TranscendentalCostFunction,
+                                                  RIDDERS,
+                                                  2,  // number of residuals
+                                                  5,  // size of x1
+                                                  5   // size of x2
+                                                  >(
+      new TranscendentalCostFunction, TAKE_OWNERSHIP, 2, options));
   TranscendentalFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, RIDDERS);
 }
 
-template<int num_rows, int num_cols>
+template <int num_rows, int num_cols>
 class SizeTestingCostFunction : public SizedCostFunction<num_rows, num_cols> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     return true;
   }
 };
@@ -241,20 +232,20 @@
 TEST(NumericDiffCostFunction, EigenRowMajorColMajorTest) {
   std::unique_ptr<CostFunction> cost_function;
   cost_function.reset(
-      new NumericDiffCostFunction<SizeTestingCostFunction<1,1>,  CENTRAL, 1, 1>(
-          new SizeTestingCostFunction<1,1>, ceres::TAKE_OWNERSHIP));
+      new NumericDiffCostFunction<SizeTestingCostFunction<1, 1>, CENTRAL, 1, 1>(
+          new SizeTestingCostFunction<1, 1>, ceres::TAKE_OWNERSHIP));
 
   cost_function.reset(
-      new NumericDiffCostFunction<SizeTestingCostFunction<2,1>,  CENTRAL, 2, 1>(
-          new SizeTestingCostFunction<2,1>, ceres::TAKE_OWNERSHIP));
+      new NumericDiffCostFunction<SizeTestingCostFunction<2, 1>, CENTRAL, 2, 1>(
+          new SizeTestingCostFunction<2, 1>, ceres::TAKE_OWNERSHIP));
 
   cost_function.reset(
-      new NumericDiffCostFunction<SizeTestingCostFunction<1,2>,  CENTRAL, 1, 2>(
-          new SizeTestingCostFunction<1,2>, ceres::TAKE_OWNERSHIP));
+      new NumericDiffCostFunction<SizeTestingCostFunction<1, 2>, CENTRAL, 1, 2>(
+          new SizeTestingCostFunction<1, 2>, ceres::TAKE_OWNERSHIP));
 
   cost_function.reset(
-      new NumericDiffCostFunction<SizeTestingCostFunction<2,2>,  CENTRAL, 2, 2>(
-          new SizeTestingCostFunction<2,2>, ceres::TAKE_OWNERSHIP));
+      new NumericDiffCostFunction<SizeTestingCostFunction<2, 2>, CENTRAL, 2, 2>(
+          new SizeTestingCostFunction<2, 2>, ceres::TAKE_OWNERSHIP));
 
   cost_function.reset(
       new NumericDiffCostFunction<EasyFunctor, CENTRAL, ceres::DYNAMIC, 1, 1>(
@@ -288,21 +279,20 @@
       new NumericDiffCostFunction<EasyFunctor,
                                   CENTRAL,
                                   ceres::DYNAMIC,
-                                  5,  /* size of x1 */
-                                  5   /* size of x2 */>(
-                                      new EasyFunctor, TAKE_OWNERSHIP, 3));
+                                  5,  // size of x1
+                                  5   // size of x2
+                                  >(new EasyFunctor, TAKE_OWNERSHIP, 3));
   EasyFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, CENTRAL);
 }
 
 TEST(NumericDiffCostFunction, ExponentialFunctorRidders) {
   std::unique_ptr<CostFunction> cost_function;
-  cost_function.reset(
-      new NumericDiffCostFunction<ExponentialFunctor,
-                                  RIDDERS,
-                                  1,  /* number of residuals */
-                                  1   /* size of x1 */>(
-             new ExponentialFunctor));
+  cost_function.reset(new NumericDiffCostFunction<ExponentialFunctor,
+                                                  RIDDERS,
+                                                  1,  // number of residuals
+                                                  1   // size of x1
+                                                  >(new ExponentialFunctor));
   ExponentialFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function);
 }
@@ -312,9 +302,9 @@
   cost_function.reset(
       new NumericDiffCostFunction<ExponentialCostFunction,
                                   RIDDERS,
-                                  1,  /* number of residuals */
-                                  1   /* size of x1 */>(
-             new ExponentialCostFunction));
+                                  1,  // number of residuals
+                                  1   // size of x1
+                                  >(new ExponentialCostFunction));
   ExponentialFunctor functor;
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function);
 }
@@ -326,14 +316,16 @@
   // presence of random noise.
   options.ridders_relative_initial_step_size = 10.0;
 
-  cost_function.reset(
-      new NumericDiffCostFunction<RandomizedFunctor,
-                                  RIDDERS,
-                                  1,  /* number of residuals */
-                                  1   /* size of x1 */>(
-             new RandomizedFunctor(kNoiseFactor, kRandomSeed), TAKE_OWNERSHIP,
-             1, options));
-  RandomizedFunctor functor (kNoiseFactor, kRandomSeed);
+  cost_function.reset(new NumericDiffCostFunction<RandomizedFunctor,
+                                                  RIDDERS,
+                                                  1,  // number of residuals
+                                                  1   // size of x1
+                                                  >(
+      new RandomizedFunctor(kNoiseFactor, kRandomSeed),
+      TAKE_OWNERSHIP,
+      1,
+      options));
+  RandomizedFunctor functor(kNoiseFactor, kRandomSeed);
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function);
 }
 
@@ -344,14 +336,16 @@
   // presence of random noise.
   options.ridders_relative_initial_step_size = 10.0;
 
-  cost_function.reset(
-      new NumericDiffCostFunction<RandomizedCostFunction,
-                                  RIDDERS,
-                                  1,  /* number of residuals */
-                                  1   /* size of x1 */>(
-             new RandomizedCostFunction(kNoiseFactor, kRandomSeed),
-             TAKE_OWNERSHIP, 1, options));
-  RandomizedFunctor functor (kNoiseFactor, kRandomSeed);
+  cost_function.reset(new NumericDiffCostFunction<RandomizedCostFunction,
+                                                  RIDDERS,
+                                                  1,  // number of residuals
+                                                  1   // size of x1
+                                                  >(
+      new RandomizedCostFunction(kNoiseFactor, kRandomSeed),
+      TAKE_OWNERSHIP,
+      1,
+      options));
+  RandomizedFunctor functor(kNoiseFactor, kRandomSeed);
   functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function);
 }
 
diff --git a/internal/ceres/numeric_diff_test_utils.cc b/internal/ceres/numeric_diff_test_utils.cc
index ab1b5f8..d833bbb 100644
--- a/internal/ceres/numeric_diff_test_utils.cc
+++ b/internal/ceres/numeric_diff_test_utils.cc
@@ -33,12 +33,12 @@
 
 #include <algorithm>
 #include <cmath>
+
 #include "ceres/cost_function.h"
 #include "ceres/test_util.h"
 #include "ceres/types.h"
 #include "gtest/gtest.h"
 
-
 namespace ceres {
 namespace internal {
 
@@ -55,23 +55,22 @@
 }
 
 void EasyFunctor::ExpectCostFunctionEvaluationIsNearlyCorrect(
-    const CostFunction& cost_function,
-    NumericDiffMethodType method) const {
-  // The x1[0] is made deliberately small to test the performance near
-  // zero.
+    const CostFunction& cost_function, NumericDiffMethodType method) const {
+  // The x1[0] is made deliberately small to test the performance near zero.
+  // clang-format off
   double x1[] = { 1e-64, 2.0, 3.0, 4.0, 5.0 };
   double x2[] = { 9.0, 9.0, 5.0, 5.0, 1.0 };
   double *parameters[] = { &x1[0], &x2[0] };
+  // clang-format on
 
   double dydx1[15];  // 3 x 5, row major.
   double dydx2[15];  // 3 x 5, row major.
-  double *jacobians[2] = { &dydx1[0], &dydx2[0] };
+  double* jacobians[2] = {&dydx1[0], &dydx2[0]};
 
-  double residuals[3] = {-1e-100, -2e-100, -3e-100 };
+  double residuals[3] = {-1e-100, -2e-100, -3e-100};
 
-  ASSERT_TRUE(cost_function.Evaluate(&parameters[0],
-                                     &residuals[0],
-                                     &jacobians[0]));
+  ASSERT_TRUE(
+      cost_function.Evaluate(&parameters[0], &residuals[0], &jacobians[0]));
 
   double expected_residuals[3];
   EasyFunctor functor;
@@ -97,12 +96,14 @@
   }
 
   for (int i = 0; i < 5; ++i) {
+    // clang-format off
     ExpectClose(x2[i],                    dydx1[5 * 0 + i], tolerance);  // y1
     ExpectClose(x1[i],                    dydx2[5 * 0 + i], tolerance);
     ExpectClose(2 * x2[i] * residuals[0], dydx1[5 * 1 + i], tolerance);  // y2
     ExpectClose(2 * x1[i] * residuals[0], dydx2[5 * 1 + i], tolerance);
     ExpectClose(0.0,                      dydx1[5 * 2 + i], tolerance);  // y3
     ExpectClose(2 * x2[i],                dydx2[5 * 2 + i], tolerance);
+    // clang-format on
   }
 }
 
@@ -119,14 +120,13 @@
 }
 
 void TranscendentalFunctor::ExpectCostFunctionEvaluationIsNearlyCorrect(
-    const CostFunction& cost_function,
-    NumericDiffMethodType method) const {
-
+    const CostFunction& cost_function, NumericDiffMethodType method) const {
   struct TestParameterBlocks {
     double x1[5];
     double x2[5];
   };
 
+  // clang-format off
   std::vector<TestParameterBlocks> kTests =  {
     { { 1.0, 2.0, 3.0, 4.0, 5.0 },  // No zeros.
       { 9.0, 9.0, 5.0, 5.0, 1.0 },
@@ -147,21 +147,21 @@
       { 0.0, 0.0, 0.0, 0.0, 0.0 },
     },
   };
+  // clang-format on
 
   for (int k = 0; k < kTests.size(); ++k) {
-    double *x1 = &(kTests[k].x1[0]);
-    double *x2 = &(kTests[k].x2[0]);
-    double *parameters[] = { x1, x2 };
+    double* x1 = &(kTests[k].x1[0]);
+    double* x2 = &(kTests[k].x2[0]);
+    double* parameters[] = {x1, x2};
 
     double dydx1[10];
     double dydx2[10];
-    double *jacobians[2] = { &dydx1[0], &dydx2[0] };
+    double* jacobians[2] = {&dydx1[0], &dydx2[0]};
 
     double residuals[2];
 
-    ASSERT_TRUE(cost_function.Evaluate(&parameters[0],
-                                       &residuals[0],
-                                       &jacobians[0]));
+    ASSERT_TRUE(
+        cost_function.Evaluate(&parameters[0], &residuals[0], &jacobians[0]));
     double x1x2 = 0;
     for (int i = 0; i < 5; ++i) {
       x1x2 += x1[i] * x2[i];
@@ -184,39 +184,37 @@
     }
 
     for (int i = 0; i < 5; ++i) {
+      // clang-format off
       ExpectClose( x2[i] * cos(x1x2),              dydx1[5 * 0 + i], tolerance);
       ExpectClose( x1[i] * cos(x1x2),              dydx2[5 * 0 + i], tolerance);
       ExpectClose(-x2[i] * exp(-x1x2 / 10.) / 10., dydx1[5 * 1 + i], tolerance);
       ExpectClose(-x1[i] * exp(-x1x2 / 10.) / 10., dydx2[5 * 1 + i], tolerance);
+      // clang-format on
     }
   }
 }
 
-bool ExponentialFunctor::operator()(const double* x1,
-                                    double* residuals) const {
+bool ExponentialFunctor::operator()(const double* x1, double* residuals) const {
   residuals[0] = exp(x1[0]);
   return true;
 }
 
-
 void ExponentialFunctor::ExpectCostFunctionEvaluationIsNearlyCorrect(
     const CostFunction& cost_function) const {
   // Evaluating the functor at specific points for testing.
-  std::vector<double> kTests = { 1.0, 2.0, 3.0, 4.0, 5.0 };
+  std::vector<double> kTests = {1.0, 2.0, 3.0, 4.0, 5.0};
 
   // Minimal tolerance w.r.t. the cost function and the tests.
   const double kTolerance = 2e-14;
 
   for (int k = 0; k < kTests.size(); ++k) {
-    double *parameters[] = { &kTests[k] };
+    double* parameters[] = {&kTests[k]};
     double dydx;
-    double *jacobians[1] = { &dydx };
+    double* jacobians[1] = {&dydx};
     double residual;
 
-    ASSERT_TRUE(cost_function.Evaluate(&parameters[0],
-                                       &residual,
-                                       &jacobians[0]));
-
+    ASSERT_TRUE(
+        cost_function.Evaluate(&parameters[0], &residual, &jacobians[0]));
 
     double expected_result = exp(kTests[k]);
 
@@ -228,10 +226,9 @@
   }
 }
 
-bool RandomizedFunctor::operator()(const double* x1,
-                                   double* residuals) const {
-  double random_value = static_cast<double>(rand()) /
-      static_cast<double>(RAND_MAX);
+bool RandomizedFunctor::operator()(const double* x1, double* residuals) const {
+  double random_value =
+      static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
 
   // Normalize noise to [-factor, factor].
   random_value *= 2.0;
@@ -244,7 +241,7 @@
 
 void RandomizedFunctor::ExpectCostFunctionEvaluationIsNearlyCorrect(
     const CostFunction& cost_function) const {
-  std::vector<double> kTests = { 0.0, 1.0, 3.0, 4.0, 50.0 };
+  std::vector<double> kTests = {0.0, 1.0, 3.0, 4.0, 50.0};
 
   const double kTolerance = 2e-4;
 
@@ -252,14 +249,13 @@
   srand(random_seed_);
 
   for (int k = 0; k < kTests.size(); ++k) {
-    double *parameters[] = { &kTests[k] };
+    double* parameters[] = {&kTests[k]};
     double dydx;
-    double *jacobians[1] = { &dydx };
+    double* jacobians[1] = {&dydx};
     double residual;
 
-    ASSERT_TRUE(cost_function.Evaluate(&parameters[0],
-                                       &residual,
-                                       &jacobians[0]));
+    ASSERT_TRUE(
+        cost_function.Evaluate(&parameters[0], &residual, &jacobians[0]));
 
     // Expect residual to be close to x^2 w.r.t. noise factor.
     ExpectClose(residual, kTests[k] * kTests[k], noise_factor_);
diff --git a/internal/ceres/numeric_diff_test_utils.h b/internal/ceres/numeric_diff_test_utils.h
index 2a551d3..392636e 100644
--- a/internal/ceres/numeric_diff_test_utils.h
+++ b/internal/ceres/numeric_diff_test_utils.h
@@ -32,6 +32,7 @@
 #define CERES_INTERNAL_NUMERIC_DIFF_TEST_UTILS_H_
 
 #include "ceres/cost_function.h"
+#include "ceres/internal/port.h"
 #include "ceres/sized_cost_function.h"
 #include "ceres/types.h"
 
@@ -39,27 +40,26 @@
 namespace internal {
 
 // Noise factor for randomized cost function.
-static const double kNoiseFactor = 0.01;
+static constexpr double kNoiseFactor = 0.01;
 
 // Default random seed for randomized cost function.
-static const unsigned int kRandomSeed = 1234;
+static constexpr unsigned int kRandomSeed = 1234;
 
 // y1 = x1'x2      -> dy1/dx1 = x2,               dy1/dx2 = x1
 // y2 = (x1'x2)^2  -> dy2/dx1 = 2 * x2 * (x1'x2), dy2/dx2 = 2 * x1 * (x1'x2)
 // y3 = x2'x2      -> dy3/dx1 = 0,                dy3/dx2 = 2 * x2
-class EasyFunctor {
+class CERES_EXPORT_INTERNAL EasyFunctor {
  public:
   bool operator()(const double* x1, const double* x2, double* residuals) const;
   void ExpectCostFunctionEvaluationIsNearlyCorrect(
-      const CostFunction& cost_function,
-      NumericDiffMethodType method) const;
+      const CostFunction& cost_function, NumericDiffMethodType method) const;
 };
 
 class EasyCostFunction : public SizedCostFunction<3, 5, 5> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** /* not used */) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** /* not used */) const final {
     return functor_(parameters[0], parameters[1], residuals);
   }
 
@@ -72,27 +72,28 @@
 //
 // dy1/dx1 =  x2 * cos(x1'x2),            dy1/dx2 =  x1 * cos(x1'x2)
 // dy2/dx1 = -x2 * exp(-x1'x2 / 10) / 10, dy2/dx2 = -x2 * exp(-x1'x2 / 10) / 10
-class TranscendentalFunctor {
+class CERES_EXPORT TranscendentalFunctor {
  public:
   bool operator()(const double* x1, const double* x2, double* residuals) const;
   void ExpectCostFunctionEvaluationIsNearlyCorrect(
-      const CostFunction& cost_function,
-      NumericDiffMethodType method) const;
+      const CostFunction& cost_function, NumericDiffMethodType method) const;
 };
 
-class TranscendentalCostFunction : public SizedCostFunction<2, 5, 5> {
+class CERES_EXPORT_INTERNAL TranscendentalCostFunction
+    : public SizedCostFunction<2, 5, 5> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** /* not used */) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** /* not used */) const final {
     return functor_(parameters[0], parameters[1], residuals);
   }
+
  private:
   TranscendentalFunctor functor_;
 };
 
 // y = exp(x), dy/dx = exp(x)
-class ExponentialFunctor {
+class CERES_EXPORT_INTERNAL ExponentialFunctor {
  public:
   bool operator()(const double* x1, double* residuals) const;
   void ExpectCostFunctionEvaluationIsNearlyCorrect(
@@ -101,9 +102,9 @@
 
 class ExponentialCostFunction : public SizedCostFunction<1, 1> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** /* not used */) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** /* not used */) const final {
     return functor_(parameters[0], residuals);
   }
 
@@ -114,11 +115,10 @@
 // Test adaptive numeric differentiation by synthetically adding random noise
 // to a functor.
 // y = x^2 + [random noise], dy/dx ~ 2x
-class RandomizedFunctor {
+class CERES_EXPORT_INTERNAL RandomizedFunctor {
  public:
   RandomizedFunctor(double noise_factor, unsigned int random_seed)
-      : noise_factor_(noise_factor), random_seed_(random_seed) {
-  }
+      : noise_factor_(noise_factor), random_seed_(random_seed) {}
 
   bool operator()(const double* x1, double* residuals) const;
   void ExpectCostFunctionEvaluationIsNearlyCorrect(
@@ -129,15 +129,15 @@
   unsigned int random_seed_;
 };
 
-class RandomizedCostFunction : public SizedCostFunction<1, 1> {
+class CERES_EXPORT_INTERNAL RandomizedCostFunction
+    : public SizedCostFunction<1, 1> {
  public:
   RandomizedCostFunction(double noise_factor, unsigned int random_seed)
-      : functor_(noise_factor, random_seed) {
-  }
+      : functor_(noise_factor, random_seed) {}
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** /* not used */) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** /* not used */) const final {
     return functor_(parameters[0], residuals);
   }
 
@@ -145,7 +145,6 @@
   RandomizedFunctor functor_;
 };
 
-
 }  // namespace internal
 }  // namespace ceres
 
diff --git a/internal/ceres/ordered_groups_test.cc b/internal/ceres/ordered_groups_test.cc
index 8cf4324..d613a41 100644
--- a/internal/ceres/ordered_groups_test.cc
+++ b/internal/ceres/ordered_groups_test.cc
@@ -32,6 +32,7 @@
 
 #include <cstddef>
 #include <vector>
+
 #include "gtest/gtest.h"
 
 namespace ceres {
diff --git a/internal/ceres/pair_hash.h b/internal/ceres/pair_hash.h
index 80453ba..abbedcc 100644
--- a/internal/ceres/pair_hash.h
+++ b/internal/ceres/pair_hash.h
@@ -33,10 +33,11 @@
 #ifndef CERES_INTERNAL_PAIR_HASH_H_
 #define CERES_INTERNAL_PAIR_HASH_H_
 
-#include "ceres/internal/port.h"
 #include <cstdint>
 #include <utility>
 
+#include "ceres/internal/port.h"
+
 namespace ceres {
 namespace internal {
 
@@ -53,6 +54,8 @@
 // in 18 cycles if you're lucky. On x86 architectures, this requires 45
 // instructions in 27 cycles, if you're lucky.
 //
+// clang-format off
+//
 // 32bit version
 inline void hash_mix(uint32_t& a, uint32_t& b, uint32_t& c) {
   a -= b; a -= c; a ^= (c>>13);
@@ -78,6 +81,7 @@
   b -= c; b -= a; b ^= (a<<49);
   c -= a; c -= b; c ^= (b>>11);
 }
+// clang-format on
 
 inline uint32_t Hash32NumWithSeed(uint32_t num, uint32_t c) {
   // The golden ratio; an arbitrary value.
diff --git a/internal/ceres/parallel_for.h b/internal/ceres/parallel_for.h
index 2da2320..b64bd31 100644
--- a/internal/ceres/parallel_for.h
+++ b/internal/ceres/parallel_for.h
@@ -34,6 +34,7 @@
 #include <functional>
 
 #include "ceres/context_impl.h"
+#include "ceres/internal/port.h"
 
 namespace ceres {
 namespace internal {
@@ -45,22 +46,24 @@
 // Execute the function for every element in the range [start, end) with at most
 // num_threads. It will execute all the work on the calling thread if
 // num_threads is 1.
-void ParallelFor(ContextImpl* context,
-                 int start,
-                 int end,
-                 int num_threads,
-                 const std::function<void(int)>& function);
+CERES_EXPORT_INTERNAL void ParallelFor(
+    ContextImpl* context,
+    int start,
+    int end,
+    int num_threads,
+    const std::function<void(int)>& function);
 
 // Execute the function for every element in the range [start, end) with at most
 // num_threads. It will execute all the work on the calling thread if
 // num_threads is 1.  Each invocation of function() will be passed a thread_id
 // in [0, num_threads) that is guaranteed to be distinct from the value passed
 // to any concurrent execution of function().
-void ParallelFor(ContextImpl* context,
-                 int start,
-                 int end,
-                 int num_threads,
-                 const std::function<void(int thread_id, int i)>& function);
+CERES_EXPORT_INTERNAL void ParallelFor(
+    ContextImpl* context,
+    int start,
+    int end,
+    int num_threads,
+    const std::function<void(int thread_id, int i)>& function);
 }  // namespace internal
 }  // namespace ceres
 
diff --git a/internal/ceres/parallel_for_cxx.cc b/internal/ceres/parallel_for_cxx.cc
index b6ef709..4da40c0 100644
--- a/internal/ceres/parallel_for_cxx.cc
+++ b/internal/ceres/parallel_for_cxx.cc
@@ -31,9 +31,7 @@
 // This include must come before any #ifndef check on Ceres compile options.
 #include "ceres/internal/port.h"
 
-#ifdef CERES_USE_CXX11_THREADS
-
-#include "ceres/parallel_for.h"
+#ifdef CERES_USE_CXX_THREADS
 
 #include <cmath>
 #include <condition_variable>
@@ -41,6 +39,7 @@
 #include <mutex>
 
 #include "ceres/concurrent_queue.h"
+#include "ceres/parallel_for.h"
 #include "ceres/scoped_thread_token.h"
 #include "ceres/thread_token_provider.h"
 #include "glog/logging.h"
@@ -117,9 +116,7 @@
 
 }  // namespace
 
-int MaxNumThreadsAvailable() {
-  return ThreadPool::MaxNumThreadsAvailable();
-}
+int MaxNumThreadsAvailable() { return ThreadPool::MaxNumThreadsAvailable(); }
 
 // See ParallelFor (below) for more details.
 void ParallelFor(ContextImpl* context,
@@ -141,8 +138,10 @@
     return;
   }
 
-  ParallelFor(context, start, end, num_threads,
-              [&function](int /*thread_id*/, int i) { function(i); });
+  ParallelFor(
+      context, start, end, num_threads, [&function](int /*thread_id*/, int i) {
+        function(i);
+      });
 }
 
 // This implementation uses a fixed size max worker pool with a shared task
@@ -213,8 +212,7 @@
     const int thread_id = scoped_thread_token.token();
 
     // Perform each task.
-    for (int j = shared_state->start + i;
-         j < shared_state->end;
+    for (int j = shared_state->start + i; j < shared_state->end;
          j += shared_state->num_work_items) {
       function(thread_id, j);
     }
@@ -244,4 +242,4 @@
 }  // namespace internal
 }  // namespace ceres
 
-#endif // CERES_USE_CXX11_THREADS
+#endif  // CERES_USE_CXX_THREADS
diff --git a/internal/ceres/parallel_for_nothreads.cc b/internal/ceres/parallel_for_nothreads.cc
index e8f450a..d036569 100644
--- a/internal/ceres/parallel_for_nothreads.cc
+++ b/internal/ceres/parallel_for_nothreads.cc
@@ -72,7 +72,7 @@
   }
 }
 
-}
-}
+}  // namespace internal
+}  // namespace ceres
 
 #endif  // CERES_NO_THREADS
diff --git a/internal/ceres/parallel_for_openmp.cc b/internal/ceres/parallel_for_openmp.cc
index 8afe3b1..eb9d905 100644
--- a/internal/ceres/parallel_for_openmp.cc
+++ b/internal/ceres/parallel_for_openmp.cc
@@ -34,7 +34,6 @@
 #if defined(CERES_USE_OPENMP)
 
 #include "ceres/parallel_for.h"
-
 #include "ceres/scoped_thread_token.h"
 #include "ceres/thread_token_provider.h"
 #include "glog/logging.h"
@@ -43,9 +42,7 @@
 namespace ceres {
 namespace internal {
 
-int MaxNumThreadsAvailable() {
-  return omp_get_max_threads();
-}
+int MaxNumThreadsAvailable() { return omp_get_max_threads(); }
 
 void ParallelFor(ContextImpl* context,
                  int start,
diff --git a/internal/ceres/parallel_for_test.cc b/internal/ceres/parallel_for_test.cc
index 04e5783..434f993 100644
--- a/internal/ceres/parallel_for_test.cc
+++ b/internal/ceres/parallel_for_test.cc
@@ -29,7 +29,9 @@
 // Author: vitus@google.com (Michael Vitus)
 
 // This include must come before any #ifndef check on Ceres compile options.
+// clang-format off
 #include "ceres/internal/port.h"
+// clang-format on
 
 #include "ceres/parallel_for.h"
 
@@ -64,8 +66,9 @@
 
   for (int num_threads = 1; num_threads <= 8; ++num_threads) {
     std::vector<int> values(size, 0);
-    ParallelFor(&context, 0, size, num_threads,
-                [&values](int i) { values[i] = std::sqrt(i); });
+    ParallelFor(&context, 0, size, num_threads, [&values](int i) {
+      values[i] = std::sqrt(i);
+    });
     EXPECT_THAT(values, ElementsAreArray(expected_results));
   }
 }
@@ -84,8 +87,10 @@
 
   for (int num_threads = 1; num_threads <= 8; ++num_threads) {
     std::vector<int> values(size, 0);
-    ParallelFor(&context, 0, size, num_threads,
-                [&values](int thread_id, int i) { values[i] = std::sqrt(i); });
+    ParallelFor(
+        &context, 0, size, num_threads, [&values](int thread_id, int i) {
+          values[i] = std::sqrt(i);
+        });
     EXPECT_THAT(values, ElementsAreArray(expected_results));
   }
 }
@@ -146,7 +151,10 @@
   std::mutex mutex;
   std::condition_variable condition;
   int count = 0;
-  ParallelFor(&context, 0, 2, 2,
+  ParallelFor(&context,
+              0,
+              2,
+              2,
               [&x, &mutex, &condition, &count](int thread_id, int i) {
                 std::unique_lock<std::mutex> lock(mutex);
                 x[i] = thread_id;
@@ -155,7 +163,7 @@
                 condition.wait(lock, [&]() { return count == 2; });
               });
 
-  EXPECT_THAT(x, UnorderedElementsAreArray({0,1}));
+  EXPECT_THAT(x, UnorderedElementsAreArray({0, 1}));
 }
 #endif  // CERES_NO_THREADS
 
diff --git a/internal/ceres/parallel_utils.h b/internal/ceres/parallel_utils.h
index 1291428..89d2110 100644
--- a/internal/ceres/parallel_utils.h
+++ b/internal/ceres/parallel_utils.h
@@ -31,6 +31,8 @@
 #ifndef CERES_INTERNAL_PARALLEL_UTILS_H_
 #define CERES_INTERNAL_PARALLEL_UTILS_H_
 
+#include "ceres/internal/port.h"
+
 namespace ceres {
 namespace internal {
 
@@ -59,7 +61,10 @@
 //    });
 // which in each iteration will produce i and j satisfying
 // 0 <= i <= j < n
-void LinearIndexToUpperTriangularIndex(int k, int n, int* i, int* j);
+CERES_EXPORT_INTERNAL void LinearIndexToUpperTriangularIndex(int k,
+                                                             int n,
+                                                             int* i,
+                                                             int* j);
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/parallel_utils_test.cc b/internal/ceres/parallel_utils_test.cc
index f997d25..53870bb 100644
--- a/internal/ceres/parallel_utils_test.cc
+++ b/internal/ceres/parallel_utils_test.cc
@@ -29,7 +29,10 @@
 // Author: wjr@google.com (William Rucklidge)
 
 // This include must come before any #ifndef check on Ceres compile options.
+// clang-format off
 #include "ceres/internal/port.h"
+// clang-format on
+
 #include "ceres/parallel_utils.h"
 
 #include "glog/logging.h"
diff --git a/internal/ceres/parameter_block.h b/internal/ceres/parameter_block.h
index 7f2a911..88943df 100644
--- a/internal/ceres/parameter_block.h
+++ b/internal/ceres/parameter_block.h
@@ -1,5 +1,5 @@
 // Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2015 Google Inc. All rights reserved.
+// Copyright 2019 Google Inc. All rights reserved.
 // http://ceres-solver.org/
 //
 // Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,7 @@
 #include <memory>
 #include <string>
 #include <unordered_set>
+
 #include "ceres/array_utils.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/port.h"
@@ -69,8 +70,8 @@
   // of the parameter block inside a Program (if any).
   ParameterBlock(double* user_state, int size, int index)
       : user_state_(user_state),
-        state_(user_state),
         size_(size),
+        state_(user_state),
         index_(index) {}
 
   ParameterBlock(double* user_state,
@@ -78,8 +79,8 @@
                  int index,
                  LocalParameterization* local_parameterization)
       : user_state_(user_state),
-        state_(user_state),
         size_(size),
+        state_(user_state),
         index_(index) {
     if (local_parameterization != nullptr) {
       SetParameterization(local_parameterization);
@@ -123,7 +124,6 @@
   // Set this parameter block to vary or not.
   void SetConstant() { is_set_constant_ = true; }
   void SetVarying() { is_set_constant_ = false; }
-  bool IsSetConstantByUser() const { return is_set_constant_; }
   bool IsConstant() const { return (is_set_constant_ || LocalSize() == 0); }
 
   double UpperBound(int index) const {
@@ -166,23 +166,19 @@
                : local_parameterization_->LocalSize();
   }
 
-  // Set the parameterization. The parameterization can be set exactly once;
-  // multiple calls to set the parameterization to different values will crash.
-  // It is an error to pass nullptr for the parameterization. The parameter
-  // block does not take ownership of the parameterization.
+  // Set the parameterization. The parameter block does not take
+  // ownership of the parameterization.
   void SetParameterization(LocalParameterization* new_parameterization) {
-    CHECK(new_parameterization != nullptr)
-        << "nullptr parameterization invalid.";
     // Nothing to do if the new parameterization is the same as the
     // old parameterization.
     if (new_parameterization == local_parameterization_) {
       return;
     }
 
-    CHECK(local_parameterization_ == nullptr)
-        << "Can't re-set the local parameterization; it leads to "
-        << "ambiguous ownership. Current local parameterization is: "
-        << local_parameterization_;
+    if (new_parameterization == nullptr) {
+      local_parameterization_ = nullptr;
+      return;
+    }
 
     CHECK(new_parameterization->GlobalSize() == size_)
         << "Invalid parameterization for parameter block. The parameter block "
@@ -190,9 +186,9 @@
         << "size of " << new_parameterization->GlobalSize() << ". Did you "
         << "accidentally use the wrong parameter block or parameterization?";
 
-    CHECK_GT(new_parameterization->LocalSize(), 0)
+    CHECK_GE(new_parameterization->LocalSize(), 0)
         << "Invalid parameterization. Parameterizations must have a "
-        << "positive dimensional tangent space.";
+        << "non-negative dimensional tangent space.";
 
     local_parameterization_ = new_parameterization;
     local_parameterization_jacobian_.reset(
@@ -371,13 +367,13 @@
 
   // The index of the parameter. This is used by various other parts of Ceres to
   // permit switching from a ParameterBlock* to an index in another array.
-  int32_t index_ = -1;
+  int index_ = -1;
 
   // The offset of this parameter block inside a larger state vector.
-  int32_t state_offset_ = -1;
+  int state_offset_ = -1;
 
   // The offset of this parameter block inside a larger delta vector.
-  int32_t delta_offset_ = -1;
+  int delta_offset_ = -1;
 
   // If non-null, contains the residual blocks this parameter block is in.
   std::unique_ptr<ResidualBlockSet> residual_blocks_;
diff --git a/internal/ceres/parameter_block_ordering.cc b/internal/ceres/parameter_block_ordering.cc
index ef521c0..9899c24 100644
--- a/internal/ceres/parameter_block_ordering.cc
+++ b/internal/ceres/parameter_block_ordering.cc
@@ -50,11 +50,11 @@
 using std::vector;
 
 int ComputeStableSchurOrdering(const Program& program,
-                         vector<ParameterBlock*>* ordering) {
+                               vector<ParameterBlock*>* ordering) {
   CHECK(ordering != nullptr);
   ordering->clear();
   EventLogger event_logger("ComputeStableSchurOrdering");
-  std::unique_ptr<Graph< ParameterBlock*> > graph(CreateHessianGraph(program));
+  std::unique_ptr<Graph<ParameterBlock*>> graph(CreateHessianGraph(program));
   event_logger.AddEvent("CreateHessianGraph");
 
   const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
@@ -86,7 +86,7 @@
   CHECK(ordering != nullptr);
   ordering->clear();
 
-  std::unique_ptr<Graph< ParameterBlock*> > graph(CreateHessianGraph(program));
+  std::unique_ptr<Graph<ParameterBlock*>> graph(CreateHessianGraph(program));
   int independent_set_size = IndependentSetOrdering(*graph, ordering);
   const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
 
@@ -106,7 +106,7 @@
   CHECK(ordering != nullptr);
   ordering->Clear();
   const vector<ParameterBlock*> parameter_blocks = program.parameter_blocks();
-  std::unique_ptr<Graph< ParameterBlock*> > graph(CreateHessianGraph(program));
+  std::unique_ptr<Graph<ParameterBlock*>> graph(CreateHessianGraph(program));
 
   int num_covered = 0;
   int round = 0;
diff --git a/internal/ceres/parameter_block_ordering.h b/internal/ceres/parameter_block_ordering.h
index f996929..82ab75d 100644
--- a/internal/ceres/parameter_block_ordering.h
+++ b/internal/ceres/parameter_block_ordering.h
@@ -32,8 +32,10 @@
 #define CERES_INTERNAL_PARAMETER_BLOCK_ORDERING_H_
 
 #include <vector>
-#include "ceres/ordered_groups.h"
+
 #include "ceres/graph.h"
+#include "ceres/internal/port.h"
+#include "ceres/ordered_groups.h"
 #include "ceres/types.h"
 
 namespace ceres {
@@ -55,33 +57,34 @@
 // ordering = [independent set,
 //             complement of the independent set,
 //             fixed blocks]
-int ComputeSchurOrdering(const Program& program,
-                         std::vector<ParameterBlock* >* ordering);
+CERES_EXPORT_INTERNAL int ComputeSchurOrdering(
+    const Program& program, std::vector<ParameterBlock*>* ordering);
 
 // Same as above, except that ties while computing the independent set
 // ordering are resolved in favour of the order in which the parameter
 // blocks occur in the program.
-int ComputeStableSchurOrdering(const Program& program,
-                               std::vector<ParameterBlock* >* ordering);
+CERES_EXPORT_INTERNAL int ComputeStableSchurOrdering(
+    const Program& program, std::vector<ParameterBlock*>* ordering);
 
 // Use an approximate independent set ordering to decompose the
 // parameter blocks of a problem in a sequence of independent
 // sets. The ordering covers all the non-constant parameter blocks in
 // the program.
-void ComputeRecursiveIndependentSetOrdering(const Program& program,
-                                            ParameterBlockOrdering* ordering);
+CERES_EXPORT_INTERNAL void ComputeRecursiveIndependentSetOrdering(
+    const Program& program, ParameterBlockOrdering* ordering);
 
 // Builds a graph on the parameter blocks of a Problem, whose
 // structure reflects the sparsity structure of the Hessian. Each
 // vertex corresponds to a parameter block in the Problem except for
 // parameter blocks that are marked constant. An edge connects two
 // parameter blocks, if they co-occur in a residual block.
-Graph<ParameterBlock*>* CreateHessianGraph(const Program& program);
+CERES_EXPORT_INTERNAL Graph<ParameterBlock*>* CreateHessianGraph(
+    const Program& program);
 
 // Iterate over each of the groups in order of their priority and fill
 // summary with their sizes.
-void OrderingToGroupSizes(const ParameterBlockOrdering* ordering,
-                          std::vector<int>* group_sizes);
+CERES_EXPORT_INTERNAL void OrderingToGroupSizes(
+    const ParameterBlockOrdering* ordering, std::vector<int>* group_sizes);
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/parameter_block_ordering_test.cc b/internal/ceres/parameter_block_ordering_test.cc
index ba61be6..1078893 100644
--- a/internal/ceres/parameter_block_ordering_test.cc
+++ b/internal/ceres/parameter_block_ordering_test.cc
@@ -53,16 +53,16 @@
 
 template <int M, int... Ns>
 class DummyCostFunction : public SizedCostFunction<M, Ns...> {
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     return true;
   }
 };
 
 class SchurOrderingTest : public ::testing::Test {
- protected :
-  virtual void SetUp() {
+ protected:
+  void SetUp() final {
     // The explicit calls to AddParameterBlock are necessary because
     // the below tests depend on the specific numbering of the
     // parameter blocks.
@@ -75,8 +75,8 @@
     problem_.AddResidualBlock(new DummyCostFunction<6, 5, 4>, NULL, z_, y_);
     problem_.AddResidualBlock(new DummyCostFunction<3, 3, 5>, NULL, x_, z_);
     problem_.AddResidualBlock(new DummyCostFunction<7, 5, 3>, NULL, z_, x_);
-    problem_.AddResidualBlock(new DummyCostFunction<1, 5, 3, 6>, NULL,
-                              z_, x_, w_);
+    problem_.AddResidualBlock(
+        new DummyCostFunction<1, 5, 3, 6>, NULL, z_, x_, w_);
   }
 
   ProblemImpl problem_;
diff --git a/internal/ceres/parameter_block_test.cc b/internal/ceres/parameter_block_test.cc
index e33db48..a5a4230 100644
--- a/internal/ceres/parameter_block_test.cc
+++ b/internal/ceres/parameter_block_test.cc
@@ -30,13 +30,13 @@
 
 #include "ceres/parameter_block.h"
 
-#include "gtest/gtest.h"
 #include "ceres/internal/eigen.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
 
-TEST(ParameterBlock, SetLocalParameterizationDiesOnSizeMismatch) {
+TEST(ParameterBlock, SetParameterizationDiesOnSizeMismatch) {
   double x[3] = {1.0, 2.0, 3.0};
   ParameterBlock parameter_block(x, 3, -1);
   std::vector<int> indices;
@@ -46,7 +46,7 @@
       parameter_block.SetParameterization(&subset_wrong_size), "global");
 }
 
-TEST(ParameterBlock, SetLocalParameterizationWithSameExistingParameterization) {
+TEST(ParameterBlock, SetParameterizationWithSameExistingParameterization) {
   double x[3] = {1.0, 2.0, 3.0};
   ParameterBlock parameter_block(x, 3, -1);
   std::vector<int> indices;
@@ -56,62 +56,44 @@
   parameter_block.SetParameterization(&subset);
 }
 
-TEST(ParameterBlock, SetLocalParameterizationDiesWhenResettingToNull) {
+TEST(ParameterBlock, SetParameterizationAllowsResettingToNull) {
   double x[3] = {1.0, 2.0, 3.0};
   ParameterBlock parameter_block(x, 3, -1);
   std::vector<int> indices;
   indices.push_back(1);
   SubsetParameterization subset(3, indices);
   parameter_block.SetParameterization(&subset);
-  EXPECT_DEATH_IF_SUPPORTED(parameter_block.SetParameterization(nullptr), "nullptr");
+  EXPECT_EQ(parameter_block.local_parameterization(), &subset);
+  parameter_block.SetParameterization(nullptr);
+  EXPECT_EQ(parameter_block.local_parameterization(), nullptr);
 }
 
 TEST(ParameterBlock,
-     SetLocalParameterizationDiesWhenResettingToDifferentParameterization) {
+     SetParameterizationAllowsResettingToDifferentParameterization) {
   double x[3] = {1.0, 2.0, 3.0};
   ParameterBlock parameter_block(x, 3, -1);
   std::vector<int> indices;
   indices.push_back(1);
   SubsetParameterization subset(3, indices);
   parameter_block.SetParameterization(&subset);
+  EXPECT_EQ(parameter_block.local_parameterization(), &subset);
+
   SubsetParameterization subset_different(3, indices);
-  EXPECT_DEATH_IF_SUPPORTED(
-      parameter_block.SetParameterization(&subset_different), "re-set");
+  parameter_block.SetParameterization(&subset_different);
+  EXPECT_EQ(parameter_block.local_parameterization(), &subset_different);
 }
 
-TEST(ParameterBlock, SetLocalParameterizationDiesOnNullParameterization) {
+TEST(ParameterBlock, SetParameterizationAndNormalOperation) {
   double x[3] = {1.0, 2.0, 3.0};
   ParameterBlock parameter_block(x, 3, -1);
   std::vector<int> indices;
   indices.push_back(1);
-  EXPECT_DEATH_IF_SUPPORTED(parameter_block.SetParameterization(nullptr), "nullptr");
-}
-
-TEST(ParameterBlock, SetParameterizationDiesOnZeroLocalSize) {
-  double x[3] = {1.0, 2.0, 3.0};
-  ParameterBlock parameter_block(x, 3, -1);
-  std::vector<int> indices;
-  indices.push_back(0);
-  indices.push_back(1);
-  indices.push_back(2);
-  SubsetParameterization subset(3, indices);
-  EXPECT_DEATH_IF_SUPPORTED(parameter_block.SetParameterization(&subset),
-                            "positive dimensional tangent");
-}
-
-TEST(ParameterBlock, SetLocalParameterizationAndNormalOperation) {
-  double x[3] = { 1.0, 2.0, 3.0 };
-  ParameterBlock parameter_block(x, 3, -1);
-  std::vector<int> indices;
-  indices.push_back(1);
   SubsetParameterization subset(3, indices);
   parameter_block.SetParameterization(&subset);
 
   // Ensure the local parameterization jacobian result is correctly computed.
   ConstMatrixRef local_parameterization_jacobian(
-      parameter_block.LocalParameterizationJacobian(),
-      3,
-      2);
+      parameter_block.LocalParameterizationJacobian(), 3, 2);
   ASSERT_EQ(1.0, local_parameterization_jacobian(0, 0));
   ASSERT_EQ(0.0, local_parameterization_jacobian(0, 1));
   ASSERT_EQ(0.0, local_parameterization_jacobian(1, 0));
@@ -121,7 +103,7 @@
 
   // Check that updating works as expected.
   double x_plus_delta[3];
-  double delta[2] = { 0.5, 0.3 };
+  double delta[2] = {0.5, 0.3};
   parameter_block.Plus(x, delta, x_plus_delta);
   ASSERT_EQ(1.5, x_plus_delta[0]);
   ASSERT_EQ(2.0, x_plus_delta[1]);
@@ -131,25 +113,24 @@
 struct TestParameterization : public LocalParameterization {
  public:
   virtual ~TestParameterization() {}
-  virtual bool Plus(const double* x,
-                    const double* delta,
-                    double* x_plus_delta) const {
+  bool Plus(const double* x,
+            const double* delta,
+            double* x_plus_delta) const final {
     LOG(FATAL) << "Shouldn't get called.";
     return true;
   }
-  virtual bool ComputeJacobian(const double* x,
-                               double* jacobian) const {
+  bool ComputeJacobian(const double* x, double* jacobian) const final {
     jacobian[0] = *x * 2;
     return true;
   }
 
-  virtual int GlobalSize() const { return 1; }
-  virtual int LocalSize() const { return 1; }
+  int GlobalSize() const final { return 1; }
+  int LocalSize() const final { return 1; }
 };
 
 TEST(ParameterBlock, SetStateUpdatesLocalParameterizationJacobian) {
   TestParameterization test_parameterization;
-  double x[1] = { 1.0 };
+  double x[1] = {1.0};
   ParameterBlock parameter_block(x, 1, -1, &test_parameterization);
 
   EXPECT_EQ(2.0, *parameter_block.LocalParameterizationJacobian());
@@ -160,10 +141,10 @@
 }
 
 TEST(ParameterBlock, PlusWithNoLocalParameterization) {
-  double x[2] = { 1.0, 2.0 };
+  double x[2] = {1.0, 2.0};
   ParameterBlock parameter_block(x, 2, -1);
 
-  double delta[2] = { 0.2, 0.3 };
+  double delta[2] = {0.2, 0.3};
   double x_plus_delta[2];
   parameter_block.Plus(x, delta, x_plus_delta);
   EXPECT_EQ(1.2, x_plus_delta[0]);
@@ -173,19 +154,17 @@
 // Stops computing the jacobian after the first time.
 class BadLocalParameterization : public LocalParameterization {
  public:
-  BadLocalParameterization()
-      : calls_(0) {
-  }
+  BadLocalParameterization() : calls_(0) {}
 
   virtual ~BadLocalParameterization() {}
-  virtual bool Plus(const double* x,
-                    const double* delta,
-                    double* x_plus_delta) const {
+  bool Plus(const double* x,
+            const double* delta,
+            double* x_plus_delta) const final {
     *x_plus_delta = *x + *delta;
     return true;
   }
 
-  virtual bool ComputeJacobian(const double* x, double* jacobian) const {
+  bool ComputeJacobian(const double* x, double* jacobian) const final {
     if (calls_ == 0) {
       jacobian[0] = 0;
     }
@@ -193,8 +172,8 @@
     return true;
   }
 
-  virtual int GlobalSize() const { return 1;}
-  virtual int LocalSize()  const { return 1;}
+  int GlobalSize() const final { return 1; }
+  int LocalSize() const final { return 1; }
 
  private:
   mutable int calls_;
@@ -248,5 +227,40 @@
   EXPECT_EQ(x_plus_delta[1], -1.0);
 }
 
+TEST(ParameterBlock, ResetLocalParameterizationToNull) {
+  double x[3] = {1.0, 2.0, 3.0};
+  ParameterBlock parameter_block(x, 3, -1);
+  std::vector<int> indices;
+  indices.push_back(1);
+  SubsetParameterization subset(3, indices);
+  parameter_block.SetParameterization(&subset);
+  EXPECT_EQ(parameter_block.local_parameterization(), &subset);
+  parameter_block.SetParameterization(nullptr);
+  EXPECT_EQ(parameter_block.local_parameterization(), nullptr);
+}
+
+TEST(ParameterBlock, ResetLocalParameterizationToNotNull) {
+  double x[3] = {1.0, 2.0, 3.0};
+  ParameterBlock parameter_block(x, 3, -1);
+  std::vector<int> indices;
+  indices.push_back(1);
+  SubsetParameterization subset(3, indices);
+  parameter_block.SetParameterization(&subset);
+  EXPECT_EQ(parameter_block.local_parameterization(), &subset);
+
+  SubsetParameterization subset_different(3, indices);
+  parameter_block.SetParameterization(&subset_different);
+  EXPECT_EQ(parameter_block.local_parameterization(), &subset_different);
+}
+
+TEST(ParameterBlock, SetNullLocalParameterization) {
+  double x[3] = {1.0, 2.0, 3.0};
+  ParameterBlock parameter_block(x, 3, -1);
+  EXPECT_EQ(parameter_block.local_parameterization(), nullptr);
+
+  parameter_block.SetParameterization(nullptr);
+  EXPECT_EQ(parameter_block.local_parameterization(), nullptr);
+}
+
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/parameter_dims_test.cc b/internal/ceres/parameter_dims_test.cc
index f33536f..ee3be8f 100644
--- a/internal/ceres/parameter_dims_test.cc
+++ b/internal/ceres/parameter_dims_test.cc
@@ -25,29 +25,31 @@
 #include "ceres/internal/parameter_dims.h"
 
 #include <gtest/gtest.h>
+
 #include <type_traits>
+#include <utility>
 
 namespace ceres {
 namespace internal {
 
 // Is valid parameter dims unit test
-static_assert(IsValidParameterDimensionSequence(integer_sequence<int>()) ==
+static_assert(IsValidParameterDimensionSequence(std::integer_sequence<int>()) ==
                   true,
               "Unit test of is valid parameter dimension sequence failed.");
-static_assert(
-    IsValidParameterDimensionSequence(integer_sequence<int, 2, 1>()) == true,
-    "Unit test of is valid parameter dimension sequence failed.");
-static_assert(
-    IsValidParameterDimensionSequence(integer_sequence<int, 0, 1>()) == false,
-    "Unit test of is valid parameter dimension sequence failed.");
-static_assert(
-    IsValidParameterDimensionSequence(integer_sequence<int, 3, 0>()) == false,
-    "Unit test of is valid parameter dimension sequence failed.");
+static_assert(IsValidParameterDimensionSequence(
+                  std::integer_sequence<int, 2, 1>()) == true,
+              "Unit test of is valid parameter dimension sequence failed.");
+static_assert(IsValidParameterDimensionSequence(
+                  std::integer_sequence<int, 0, 1>()) == false,
+              "Unit test of is valid parameter dimension sequence failed.");
+static_assert(IsValidParameterDimensionSequence(
+                  std::integer_sequence<int, 3, 0>()) == false,
+              "Unit test of is valid parameter dimension sequence failed.");
 
 // Static parameter dims unit test
 static_assert(
     std::is_same<StaticParameterDims<4, 2, 1>::Parameters,
-                 integer_sequence<int, 4, 2, 1>>::value == true,
+                 std::integer_sequence<int, 4, 2, 1>>::value == true,
     "Unit test of type 'parameters' for static parameter dims failed.");
 
 static_assert(StaticParameterDims<4, 2, 1>::kIsValid == true,
diff --git a/internal/ceres/partitioned_matrix_view.cc b/internal/ceres/partitioned_matrix_view.cc
index 910f241..b67bc90 100644
--- a/internal/ceres/partitioned_matrix_view.cc
+++ b/internal/ceres/partitioned_matrix_view.cc
@@ -41,117 +41,142 @@
 
 #include "ceres/linear_solver.h"
 #include "ceres/partitioned_matrix_view.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
 
-PartitionedMatrixViewBase*
-PartitionedMatrixViewBase::Create(const LinearSolver::Options& options,
-                                  const BlockSparseMatrix& matrix) {
+PartitionedMatrixViewBase* PartitionedMatrixViewBase::Create(
+    const LinearSolver::Options& options, const BlockSparseMatrix& matrix) {
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
- if ((options.row_block_size == 2) &&
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 2) &&
      (options.f_block_size == 2)) {
-   return new PartitionedMatrixView<2, 2, 2>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 2, 2>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 2) &&
      (options.f_block_size == 3)) {
-   return new PartitionedMatrixView<2, 2, 3>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 2, 3>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 2) &&
      (options.f_block_size == 4)) {
-   return new PartitionedMatrixView<2, 2, 4>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 2, 4>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 2)) {
-   return new PartitionedMatrixView<2, 2, Eigen::Dynamic>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 2, Eigen::Dynamic>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3) &&
      (options.f_block_size == 3)) {
-   return new PartitionedMatrixView<2, 3, 3>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 3, 3>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3) &&
      (options.f_block_size == 4)) {
-   return new PartitionedMatrixView<2, 3, 4>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 3, 4>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3) &&
      (options.f_block_size == 6)) {
-   return new PartitionedMatrixView<2, 3, 6>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 3, 6>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3) &&
      (options.f_block_size == 9)) {
-   return new PartitionedMatrixView<2, 3, 9>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 3, 9>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3)) {
-   return new PartitionedMatrixView<2, 3, Eigen::Dynamic>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 3, Eigen::Dynamic>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 3)) {
-   return new PartitionedMatrixView<2, 4, 3>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 4, 3>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 4)) {
-   return new PartitionedMatrixView<2, 4, 4>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 4, 4>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 6)) {
-   return new PartitionedMatrixView<2, 4, 6>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 4, 6>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 8)) {
-   return new PartitionedMatrixView<2, 4, 8>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 4, 8>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 9)) {
-   return new PartitionedMatrixView<2, 4, 9>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 2) &&
+    return new PartitionedMatrixView<2, 4, 9>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4)) {
-   return new PartitionedMatrixView<2, 4, Eigen::Dynamic>(matrix, options.elimination_groups[0]);
- }
- if (options.row_block_size == 2){
-   return new PartitionedMatrixView<2, Eigen::Dynamic, Eigen::Dynamic>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 4) &&
+    return new PartitionedMatrixView<2, 4, Eigen::Dynamic>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if (options.row_block_size == 2) {
+    return new PartitionedMatrixView<2, Eigen::Dynamic, Eigen::Dynamic>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 3) &&
+     (options.e_block_size == 3) &&
+     (options.f_block_size == 3)) {
+    return new PartitionedMatrixView<3, 3, 3>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 4) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 2)) {
-   return new PartitionedMatrixView<4, 4, 2>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 4) &&
+    return new PartitionedMatrixView<4, 4, 2>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 4) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 3)) {
-   return new PartitionedMatrixView<4, 4, 3>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 4) &&
+    return new PartitionedMatrixView<4, 4, 3>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 4) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 4)) {
-   return new PartitionedMatrixView<4, 4, 4>(matrix, options.elimination_groups[0]);
- }
- if ((options.row_block_size == 4) &&
+    return new PartitionedMatrixView<4, 4, 4>(matrix,
+                                              options.elimination_groups[0]);
+  }
+  if ((options.row_block_size == 4) &&
      (options.e_block_size == 4)) {
-   return new PartitionedMatrixView<4, 4, Eigen::Dynamic>(matrix, options.elimination_groups[0]);
- }
+    return new PartitionedMatrixView<4, 4, Eigen::Dynamic>(matrix,
+                                              options.elimination_groups[0]);
+  }
 
 #endif
   VLOG(1) << "Template specializations not found for <"
-          << options.row_block_size << ","
-          << options.e_block_size << ","
+          << options.row_block_size << "," << options.e_block_size << ","
           << options.f_block_size << ">";
-  return new PartitionedMatrixView<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>(
-               matrix, options.elimination_groups[0]);
+  return new PartitionedMatrixView<Eigen::Dynamic,
+                                   Eigen::Dynamic,
+                                   Eigen::Dynamic>(
+      matrix, options.elimination_groups[0]);
 };
 
 }  // namespace internal
diff --git a/internal/ceres/partitioned_matrix_view.h b/internal/ceres/partitioned_matrix_view.h
index 6e75060..9f204ee 100644
--- a/internal/ceres/partitioned_matrix_view.h
+++ b/internal/ceres/partitioned_matrix_view.h
@@ -42,6 +42,7 @@
 
 #include "ceres/block_structure.h"
 #include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
 #include "ceres/linear_solver.h"
 #include "ceres/small_blas.h"
 #include "glog/logging.h"
@@ -59,7 +60,7 @@
 // block structure of the matrix does not satisfy the requirements of
 // the Schur complement solver it will result in unpredictable and
 // wrong output.
-class PartitionedMatrixViewBase {
+class CERES_EXPORT_INTERNAL PartitionedMatrixViewBase {
  public:
   virtual ~PartitionedMatrixViewBase() {}
 
@@ -98,12 +99,14 @@
   virtual void UpdateBlockDiagonalFtF(
       BlockSparseMatrix* block_diagonal) const = 0;
 
+  // clang-format off
   virtual int num_col_blocks_e() const = 0;
   virtual int num_col_blocks_f() const = 0;
   virtual int num_cols_e()       const = 0;
   virtual int num_cols_f()       const = 0;
   virtual int num_rows()         const = 0;
   virtual int num_cols()         const = 0;
+  // clang-format on
 
   static PartitionedMatrixViewBase* Create(const LinearSolver::Options& options,
                                            const BlockSparseMatrix& matrix);
@@ -111,7 +114,7 @@
 
 template <int kRowBlockSize = Eigen::Dynamic,
           int kEBlockSize = Eigen::Dynamic,
-          int kFBlockSize = Eigen::Dynamic >
+          int kFBlockSize = Eigen::Dynamic>
 class PartitionedMatrixView : public PartitionedMatrixViewBase {
  public:
   // matrix = [E F], where the matrix E contains the first
@@ -119,20 +122,22 @@
   PartitionedMatrixView(const BlockSparseMatrix& matrix, int num_col_blocks_e);
 
   virtual ~PartitionedMatrixView();
-  virtual void LeftMultiplyE(const double* x, double* y) const;
-  virtual void LeftMultiplyF(const double* x, double* y) const;
-  virtual void RightMultiplyE(const double* x, double* y) const;
-  virtual void RightMultiplyF(const double* x, double* y) const;
-  virtual BlockSparseMatrix* CreateBlockDiagonalEtE() const;
-  virtual BlockSparseMatrix* CreateBlockDiagonalFtF() const;
-  virtual void UpdateBlockDiagonalEtE(BlockSparseMatrix* block_diagonal) const;
-  virtual void UpdateBlockDiagonalFtF(BlockSparseMatrix* block_diagonal) const;
-  virtual int num_col_blocks_e() const { return num_col_blocks_e_;  }
-  virtual int num_col_blocks_f() const { return num_col_blocks_f_;  }
-  virtual int num_cols_e()       const { return num_cols_e_;        }
-  virtual int num_cols_f()       const { return num_cols_f_;        }
-  virtual int num_rows()         const { return matrix_.num_rows(); }
-  virtual int num_cols()         const { return matrix_.num_cols(); }
+  void LeftMultiplyE(const double* x, double* y) const final;
+  void LeftMultiplyF(const double* x, double* y) const final;
+  void RightMultiplyE(const double* x, double* y) const final;
+  void RightMultiplyF(const double* x, double* y) const final;
+  BlockSparseMatrix* CreateBlockDiagonalEtE() const final;
+  BlockSparseMatrix* CreateBlockDiagonalFtF() const final;
+  void UpdateBlockDiagonalEtE(BlockSparseMatrix* block_diagonal) const final;
+  void UpdateBlockDiagonalFtF(BlockSparseMatrix* block_diagonal) const final;
+  // clang-format off
+  int num_col_blocks_e() const final { return num_col_blocks_e_;  }
+  int num_col_blocks_f() const final { return num_col_blocks_f_;  }
+  int num_cols_e()       const final { return num_cols_e_;        }
+  int num_cols_f()       const final { return num_cols_f_;        }
+  int num_rows()         const final { return matrix_.num_rows(); }
+  int num_cols()         const final { return matrix_.num_cols(); }
+  // clang-format on
 
  private:
   BlockSparseMatrix* CreateBlockDiagonalMatrixLayout(int start_col_block,
diff --git a/internal/ceres/partitioned_matrix_view_impl.h b/internal/ceres/partitioned_matrix_view_impl.h
index f3f548c..0b6a57f 100644
--- a/internal/ceres/partitioned_matrix_view_impl.h
+++ b/internal/ceres/partitioned_matrix_view_impl.h
@@ -28,14 +28,14 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
-#include "ceres/partitioned_matrix_view.h"
-
 #include <algorithm>
 #include <cstring>
 #include <vector>
+
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/block_structure.h"
 #include "ceres/internal/eigen.h"
+#include "ceres/partitioned_matrix_view.h"
 #include "ceres/small_blas.h"
 #include "glog/logging.h"
 
@@ -44,11 +44,8 @@
 
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
 PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
-PartitionedMatrixView(
-    const BlockSparseMatrix& matrix,
-    int num_col_blocks_e)
-    : matrix_(matrix),
-      num_col_blocks_e_(num_col_blocks_e) {
+    PartitionedMatrixView(const BlockSparseMatrix& matrix, int num_col_blocks_e)
+    : matrix_(matrix), num_col_blocks_e_(num_col_blocks_e) {
   const CompressedRowBlockStructure* bs = matrix_.block_structure();
   CHECK(bs != nullptr);
 
@@ -85,8 +82,7 @@
 
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
 PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
-~PartitionedMatrixView() {
-}
+    ~PartitionedMatrixView() {}
 
 // The next four methods don't seem to be particularly cache
 // friendly. This is an artifact of how the BlockStructure of the
@@ -94,9 +90,8 @@
 // multithreading as well as improved data layout.
 
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
-RightMultiplyE(const double* x, double* y) const {
+void PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
+    RightMultiplyE(const double* x, double* y) const {
   const CompressedRowBlockStructure* bs = matrix_.block_structure();
 
   // Iterate over the first num_row_blocks_e_ row blocks, and multiply
@@ -109,17 +104,18 @@
     const int col_block_id = cell.block_id;
     const int col_block_pos = bs->cols[col_block_id].position;
     const int col_block_size = bs->cols[col_block_id].size;
+    // clang-format off
     MatrixVectorMultiply<kRowBlockSize, kEBlockSize, 1>(
         values + cell.position, row_block_size, col_block_size,
         x + col_block_pos,
         y + row_block_pos);
+    // clang-format on
   }
 }
 
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
-RightMultiplyF(const double* x, double* y) const {
+void PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
+    RightMultiplyF(const double* x, double* y) const {
   const CompressedRowBlockStructure* bs = matrix_.block_structure();
 
   // Iterate over row blocks, and if the row block is in E, then
@@ -136,10 +132,12 @@
       const int col_block_id = cells[c].block_id;
       const int col_block_pos = bs->cols[col_block_id].position;
       const int col_block_size = bs->cols[col_block_id].size;
+      // clang-format off
       MatrixVectorMultiply<kRowBlockSize, kFBlockSize, 1>(
           values + cells[c].position, row_block_size, col_block_size,
           x + col_block_pos - num_cols_e_,
           y + row_block_pos);
+      // clang-format on
     }
   }
 
@@ -151,18 +149,19 @@
       const int col_block_id = cells[c].block_id;
       const int col_block_pos = bs->cols[col_block_id].position;
       const int col_block_size = bs->cols[col_block_id].size;
+      // clang-format off
       MatrixVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
           values + cells[c].position, row_block_size, col_block_size,
           x + col_block_pos - num_cols_e_,
           y + row_block_pos);
+      // clang-format on
     }
   }
 }
 
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
-LeftMultiplyE(const double* x, double* y) const {
+void PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
+    LeftMultiplyE(const double* x, double* y) const {
   const CompressedRowBlockStructure* bs = matrix_.block_structure();
 
   // Iterate over the first num_row_blocks_e_ row blocks, and multiply
@@ -175,17 +174,18 @@
     const int col_block_id = cell.block_id;
     const int col_block_pos = bs->cols[col_block_id].position;
     const int col_block_size = bs->cols[col_block_id].size;
+    // clang-format off
     MatrixTransposeVectorMultiply<kRowBlockSize, kEBlockSize, 1>(
         values + cell.position, row_block_size, col_block_size,
         x + row_block_pos,
         y + col_block_pos);
+    // clang-format on
   }
 }
 
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
-LeftMultiplyF(const double* x, double* y) const {
+void PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
+    LeftMultiplyF(const double* x, double* y) const {
   const CompressedRowBlockStructure* bs = matrix_.block_structure();
 
   // Iterate over row blocks, and if the row block is in E, then
@@ -202,10 +202,12 @@
       const int col_block_id = cells[c].block_id;
       const int col_block_pos = bs->cols[col_block_id].position;
       const int col_block_size = bs->cols[col_block_id].size;
+      // clang-format off
       MatrixTransposeVectorMultiply<kRowBlockSize, kFBlockSize, 1>(
         values + cells[c].position, row_block_size, col_block_size,
         x + row_block_pos,
         y + col_block_pos - num_cols_e_);
+      // clang-format on
     }
   }
 
@@ -217,10 +219,12 @@
       const int col_block_id = cells[c].block_id;
       const int col_block_pos = bs->cols[col_block_id].position;
       const int col_block_size = bs->cols[col_block_id].size;
+      // clang-format off
       MatrixTransposeVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
         values + cells[c].position, row_block_size, col_block_size,
         x + row_block_pos,
         y + col_block_pos - num_cols_e_);
+      // clang-format on
     }
   }
 }
@@ -233,7 +237,8 @@
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
 BlockSparseMatrix*
 PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
-CreateBlockDiagonalMatrixLayout(int start_col_block, int end_col_block) const {
+    CreateBlockDiagonalMatrixLayout(int start_col_block,
+                                    int end_col_block) const {
   const CompressedRowBlockStructure* bs = matrix_.block_structure();
   CompressedRowBlockStructure* block_diagonal_structure =
       new CompressedRowBlockStructure;
@@ -269,9 +274,10 @@
 }
 
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-BlockSparseMatrix*
-PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
-CreateBlockDiagonalEtE() const {
+BlockSparseMatrix* PartitionedMatrixView<kRowBlockSize,
+                                         kEBlockSize,
+                                         kFBlockSize>::CreateBlockDiagonalEtE()
+    const {
   BlockSparseMatrix* block_diagonal =
       CreateBlockDiagonalMatrixLayout(0, num_col_blocks_e_);
   UpdateBlockDiagonalEtE(block_diagonal);
@@ -279,12 +285,12 @@
 }
 
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-BlockSparseMatrix*
-PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
-CreateBlockDiagonalFtF() const {
-  BlockSparseMatrix* block_diagonal =
-      CreateBlockDiagonalMatrixLayout(
-          num_col_blocks_e_, num_col_blocks_e_ + num_col_blocks_f_);
+BlockSparseMatrix* PartitionedMatrixView<kRowBlockSize,
+                                         kEBlockSize,
+                                         kFBlockSize>::CreateBlockDiagonalFtF()
+    const {
+  BlockSparseMatrix* block_diagonal = CreateBlockDiagonalMatrixLayout(
+      num_col_blocks_e_, num_col_blocks_e_ + num_col_blocks_f_);
   UpdateBlockDiagonalFtF(block_diagonal);
   return block_diagonal;
 }
@@ -295,17 +301,15 @@
 //    block_diagonal = block_diagonal(E'E)
 //
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
-UpdateBlockDiagonalEtE(
-    BlockSparseMatrix* block_diagonal) const {
+void PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
+    UpdateBlockDiagonalEtE(BlockSparseMatrix* block_diagonal) const {
   const CompressedRowBlockStructure* bs = matrix_.block_structure();
   const CompressedRowBlockStructure* block_diagonal_structure =
       block_diagonal->block_structure();
 
   block_diagonal->SetZero();
   const double* values = matrix_.values();
-  for (int r = 0; r < num_row_blocks_e_ ; ++r) {
+  for (int r = 0; r < num_row_blocks_e_; ++r) {
     const Cell& cell = bs->rows[r].cells[0];
     const int row_block_size = bs->rows[r].block.size;
     const int block_id = cell.block_id;
@@ -313,12 +317,14 @@
     const int cell_position =
         block_diagonal_structure->rows[block_id].cells[0].position;
 
+    // clang-format off
     MatrixTransposeMatrixMultiply
         <kRowBlockSize, kEBlockSize, kRowBlockSize, kEBlockSize, 1>(
             values + cell.position, row_block_size, col_block_size,
             values + cell.position, row_block_size, col_block_size,
             block_diagonal->mutable_values() + cell_position,
             0, 0, col_block_size, col_block_size);
+    // clang-format on
   }
 }
 
@@ -328,9 +334,8 @@
 //   block_diagonal = block_diagonal(F'F)
 //
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
-UpdateBlockDiagonalFtF(BlockSparseMatrix* block_diagonal) const {
+void PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
+    UpdateBlockDiagonalFtF(BlockSparseMatrix* block_diagonal) const {
   const CompressedRowBlockStructure* bs = matrix_.block_structure();
   const CompressedRowBlockStructure* block_diagonal_structure =
       block_diagonal->block_structure();
@@ -347,12 +352,14 @@
       const int cell_position =
           block_diagonal_structure->rows[diagonal_block_id].cells[0].position;
 
+      // clang-format off
       MatrixTransposeMatrixMultiply
           <kRowBlockSize, kFBlockSize, kRowBlockSize, kFBlockSize, 1>(
               values + cells[c].position, row_block_size, col_block_size,
               values + cells[c].position, row_block_size, col_block_size,
               block_diagonal->mutable_values() + cell_position,
               0, 0, col_block_size, col_block_size);
+      // clang-format on
     }
   }
 
@@ -366,12 +373,14 @@
       const int cell_position =
           block_diagonal_structure->rows[diagonal_block_id].cells[0].position;
 
+      // clang-format off
       MatrixTransposeMatrixMultiply
           <Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, 1>(
               values + cells[c].position, row_block_size, col_block_size,
               values + cells[c].position, row_block_size, col_block_size,
               block_diagonal->mutable_values() + cell_position,
               0, 0, col_block_size, col_block_size);
+      // clang-format on
     }
   }
 }
diff --git a/internal/ceres/partitioned_matrix_view_template.py b/internal/ceres/partitioned_matrix_view_template.py
index 7894523..05a25bf 100644
--- a/internal/ceres/partitioned_matrix_view_template.py
+++ b/internal/ceres/partitioned_matrix_view_template.py
@@ -89,14 +89,14 @@
 """
 
 DYNAMIC_FILE = """
-
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
 
-template class PartitionedMatrixView<%s, %s, %s>;
+template class PartitionedMatrixView<%s,
+                                     %s,
+                                     %s>;
 
 }  // namespace internal
 }  // namespace ceres
@@ -109,7 +109,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/partitioned_matrix_view_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
@@ -125,26 +124,26 @@
 FACTORY_FILE_HEADER = """
 #include "ceres/linear_solver.h"
 #include "ceres/partitioned_matrix_view.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
 
-PartitionedMatrixViewBase*
-PartitionedMatrixViewBase::Create(const LinearSolver::Options& options,
-                                  const BlockSparseMatrix& matrix) {
+PartitionedMatrixViewBase* PartitionedMatrixViewBase::Create(
+    const LinearSolver::Options& options, const BlockSparseMatrix& matrix) {
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 """
-FACTORY = """ return new PartitionedMatrixView<%s, %s, %s>(matrix, options.elimination_groups[0]);"""
+FACTORY = """  return new PartitionedMatrixView<%s, %s, %s>(matrix,
+                                              options.elimination_groups[0]);"""
 
 FACTORY_FOOTER = """
 #endif
   VLOG(1) << "Template specializations not found for <"
-          << options.row_block_size << ","
-          << options.e_block_size << ","
+          << options.row_block_size << "," << options.e_block_size << ","
           << options.f_block_size << ">";
-  return new PartitionedMatrixView<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>(
-               matrix, options.elimination_groups[0]);
+  return new PartitionedMatrixView<Eigen::Dynamic,
+                                   Eigen::Dynamic,
+                                   Eigen::Dynamic>(
+      matrix, options.elimination_groups[0]);
 };
 
 }  // namespace internal
diff --git a/internal/ceres/partitioned_matrix_view_test.cc b/internal/ceres/partitioned_matrix_view_test.cc
index 40b49ef..b66d0b8 100644
--- a/internal/ceres/partitioned_matrix_view_test.cc
+++ b/internal/ceres/partitioned_matrix_view_test.cc
@@ -32,6 +32,7 @@
 
 #include <memory>
 #include <vector>
+
 #include "ceres/block_structure.h"
 #include "ceres/casts.h"
 #include "ceres/internal/eigen.h"
@@ -47,8 +48,8 @@
 const double kEpsilon = 1e-14;
 
 class PartitionedMatrixViewTest : public ::testing::Test {
- protected :
-  virtual void SetUp() {
+ protected:
+  void SetUp() final {
     srand(5);
     std::unique_ptr<LinearLeastSquaresProblem> problem(
         CreateLinearLeastSquaresProblemFromId(2));
@@ -61,8 +62,7 @@
     LinearSolver::Options options;
     options.elimination_groups.push_back(num_eliminate_blocks_);
     pmv_.reset(PartitionedMatrixViewBase::Create(
-                   options,
-                   *down_cast<BlockSparseMatrix*>(A_.get())));
+        options, *down_cast<BlockSparseMatrix*>(A_.get())));
   }
 
   int num_rows_;
@@ -143,9 +143,9 @@
 }
 
 TEST_F(PartitionedMatrixViewTest, BlockDiagonalEtE) {
-  std::unique_ptr<BlockSparseMatrix>
-      block_diagonal_ee(pmv_->CreateBlockDiagonalEtE());
-  const CompressedRowBlockStructure* bs  = block_diagonal_ee->block_structure();
+  std::unique_ptr<BlockSparseMatrix> block_diagonal_ee(
+      pmv_->CreateBlockDiagonalEtE());
+  const CompressedRowBlockStructure* bs = block_diagonal_ee->block_structure();
 
   EXPECT_EQ(block_diagonal_ee->num_rows(), 2);
   EXPECT_EQ(block_diagonal_ee->num_cols(), 2);
@@ -157,9 +157,9 @@
 }
 
 TEST_F(PartitionedMatrixViewTest, BlockDiagonalFtF) {
-  std::unique_ptr<BlockSparseMatrix>
-      block_diagonal_ff(pmv_->CreateBlockDiagonalFtF());
-  const CompressedRowBlockStructure* bs  = block_diagonal_ff->block_structure();
+  std::unique_ptr<BlockSparseMatrix> block_diagonal_ff(
+      pmv_->CreateBlockDiagonalFtF());
+  const CompressedRowBlockStructure* bs = block_diagonal_ff->block_structure();
 
   EXPECT_EQ(block_diagonal_ff->num_rows(), 3);
   EXPECT_EQ(block_diagonal_ff->num_cols(), 3);
diff --git a/internal/ceres/polynomial.h b/internal/ceres/polynomial.h
index 3e09bae..20071f2 100644
--- a/internal/ceres/polynomial.h
+++ b/internal/ceres/polynomial.h
@@ -33,6 +33,7 @@
 #define CERES_INTERNAL_POLYNOMIAL_SOLVER_H_
 
 #include <vector>
+
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/port.h"
 
@@ -65,13 +66,13 @@
 // On failure, a more detailed message will be written to LOG(ERROR).
 // If real is not NULL, the real parts of the roots will be returned in it.
 // Likewise, if imaginary is not NULL, imaginary parts will be returned in it.
-bool FindPolynomialRoots(const Vector& polynomial,
-                         Vector* real,
-                         Vector* imaginary);
+CERES_EXPORT_INTERNAL bool FindPolynomialRoots(const Vector& polynomial,
+                                               Vector* real,
+                                               Vector* imaginary);
 
 // Return the derivative of the given polynomial. It is assumed that
 // the input polynomial is at least of degree zero.
-Vector DifferentiatePolynomial(const Vector& polynomial);
+CERES_EXPORT_INTERNAL Vector DifferentiatePolynomial(const Vector& polynomial);
 
 // Find the minimum value of the polynomial in the interval [x_min,
 // x_max]. The minimum is obtained by computing all the roots of the
@@ -79,11 +80,11 @@
 // interval [x_min, x_max] are considered as well as the end points
 // x_min and x_max. Since polynomials are differentiable functions,
 // this ensures that the true minimum is found.
-void MinimizePolynomial(const Vector& polynomial,
-                        double x_min,
-                        double x_max,
-                        double* optimal_x,
-                        double* optimal_value);
+CERES_EXPORT_INTERNAL void MinimizePolynomial(const Vector& polynomial,
+                                              double x_min,
+                                              double x_max,
+                                              double* optimal_x,
+                                              double* optimal_value);
 
 // Given a set of function value and/or gradient samples, find a
 // polynomial whose value and gradients are exactly equal to the ones
@@ -96,7 +97,8 @@
 // Of course its possible to sample a polynomial any number of times,
 // in which case, generally speaking the spurious higher order
 // coefficients will be zero.
-Vector FindInterpolatingPolynomial(const std::vector<FunctionSample>& samples);
+CERES_EXPORT_INTERNAL Vector
+FindInterpolatingPolynomial(const std::vector<FunctionSample>& samples);
 
 // Interpolate the function described by samples with a polynomial,
 // and minimize it on the interval [x_min, x_max]. Depending on the
@@ -104,11 +106,12 @@
 // finding algorithms may fail due to numerical difficulties. But the
 // function is guaranteed to return its best guess of an answer, by
 // considering the samples and the end points as possible solutions.
-void MinimizeInterpolatingPolynomial(const std::vector<FunctionSample>& samples,
-                                     double x_min,
-                                     double x_max,
-                                     double* optimal_x,
-                                     double* optimal_value);
+CERES_EXPORT_INTERNAL void MinimizeInterpolatingPolynomial(
+    const std::vector<FunctionSample>& samples,
+    double x_min,
+    double x_max,
+    double* optimal_x,
+    double* optimal_value);
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/polynomial_test.cc b/internal/ceres/polynomial_test.cc
index 00c8534..0ff73ea 100644
--- a/internal/ceres/polynomial_test.cc
+++ b/internal/ceres/polynomial_test.cc
@@ -31,13 +31,14 @@
 
 #include "ceres/polynomial.h"
 
-#include <limits>
+#include <algorithm>
 #include <cmath>
 #include <cstddef>
-#include <algorithm>
-#include "gtest/gtest.h"
+#include <limits>
+
 #include "ceres/function_sample.h"
 #include "ceres/test_util.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
@@ -74,7 +75,7 @@
   // Multiply poly by x^2 - 2real + abs(real,imag)^2
   poly2.head(poly.size()) += poly;
   poly2.segment(1, poly.size()) -= 2 * real * poly;
-  poly2.tail(poly.size()) += (real*real + imag*imag) * poly;
+  poly2.tail(poly.size()) += (real * real + imag * imag) * poly;
   return poly2;
 }
 
@@ -90,7 +91,7 @@
 // If use_real is false, NULL is passed as the real argument to
 // FindPolynomialRoots. If use_imaginary is false, NULL is passed as the
 // imaginary argument to FindPolynomialRoots.
-template<int N>
+template <int N>
 void RunPolynomialTestRealRoots(const double (&real_roots)[N],
                                 bool use_real,
                                 bool use_imaginary,
@@ -142,32 +143,32 @@
 }
 
 TEST(Polynomial, LinearPolynomialWithPositiveRootWorks) {
-  const double roots[1] = { 42.42 };
+  const double roots[1] = {42.42};
   RunPolynomialTestRealRoots(roots, true, true, kEpsilon);
 }
 
 TEST(Polynomial, LinearPolynomialWithNegativeRootWorks) {
-  const double roots[1] = { -42.42 };
+  const double roots[1] = {-42.42};
   RunPolynomialTestRealRoots(roots, true, true, kEpsilon);
 }
 
 TEST(Polynomial, QuadraticPolynomialWithPositiveRootsWorks) {
-  const double roots[2] = { 1.0, 42.42 };
+  const double roots[2] = {1.0, 42.42};
   RunPolynomialTestRealRoots(roots, true, true, kEpsilon);
 }
 
 TEST(Polynomial, QuadraticPolynomialWithOneNegativeRootWorks) {
-  const double roots[2] = { -42.42, 1.0 };
+  const double roots[2] = {-42.42, 1.0};
   RunPolynomialTestRealRoots(roots, true, true, kEpsilon);
 }
 
 TEST(Polynomial, QuadraticPolynomialWithTwoNegativeRootsWorks) {
-  const double roots[2] = { -42.42, -1.0 };
+  const double roots[2] = {-42.42, -1.0};
   RunPolynomialTestRealRoots(roots, true, true, kEpsilon);
 }
 
 TEST(Polynomial, QuadraticPolynomialWithCloseRootsWorks) {
-  const double roots[2] = { 42.42, 42.43 };
+  const double roots[2] = {42.42, 42.43};
   RunPolynomialTestRealRoots(roots, true, false, kEpsilonLoose);
 }
 
@@ -190,37 +191,37 @@
 }
 
 TEST(Polynomial, QuarticPolynomialWorks) {
-  const double roots[4] = { 1.23e-4, 1.23e-1, 1.23e+2, 1.23e+5 };
+  const double roots[4] = {1.23e-4, 1.23e-1, 1.23e+2, 1.23e+5};
   RunPolynomialTestRealRoots(roots, true, true, kEpsilon);
 }
 
 TEST(Polynomial, QuarticPolynomialWithTwoClustersOfCloseRootsWorks) {
-  const double roots[4] = { 1.23e-1, 2.46e-1, 1.23e+5, 2.46e+5 };
+  const double roots[4] = {1.23e-1, 2.46e-1, 1.23e+5, 2.46e+5};
   RunPolynomialTestRealRoots(roots, true, true, kEpsilonLoose);
 }
 
 TEST(Polynomial, QuarticPolynomialWithTwoZeroRootsWorks) {
-  const double roots[4] = { -42.42, 0.0, 0.0, 42.42 };
+  const double roots[4] = {-42.42, 0.0, 0.0, 42.42};
   RunPolynomialTestRealRoots(roots, true, true, 2 * kEpsilonLoose);
 }
 
 TEST(Polynomial, QuarticMonomialWorks) {
-  const double roots[4] = { 0.0, 0.0, 0.0, 0.0 };
+  const double roots[4] = {0.0, 0.0, 0.0, 0.0};
   RunPolynomialTestRealRoots(roots, true, true, kEpsilon);
 }
 
 TEST(Polynomial, NullPointerAsImaginaryPartWorks) {
-  const double roots[4] = { 1.23e-4, 1.23e-1, 1.23e+2, 1.23e+5 };
+  const double roots[4] = {1.23e-4, 1.23e-1, 1.23e+2, 1.23e+5};
   RunPolynomialTestRealRoots(roots, true, false, kEpsilon);
 }
 
 TEST(Polynomial, NullPointerAsRealPartWorks) {
-  const double roots[4] = { 1.23e-4, 1.23e-1, 1.23e+2, 1.23e+5 };
+  const double roots[4] = {1.23e-4, 1.23e-1, 1.23e+2, 1.23e+5};
   RunPolynomialTestRealRoots(roots, false, true, kEpsilon);
 }
 
 TEST(Polynomial, BothOutputArgumentsNullWorks) {
-  const double roots[4] = { 1.23e-4, 1.23e-1, 1.23e+2, 1.23e+5 };
+  const double roots[4] = {1.23e-4, 1.23e-1, 1.23e+2, 1.23e+5};
   RunPolynomialTestRealRoots(roots, false, false, kEpsilon);
 }
 
@@ -279,7 +280,6 @@
   EXPECT_EQ(optimal_value, 2.0);
 }
 
-
 TEST(Polynomial, MinimizeQuadraticPolynomial) {
   // p(x) = x^2 - 3 x + 2
   // min_x = 3/2
@@ -294,8 +294,8 @@
   double min_x = -2.0;
   double max_x = 2.0;
   MinimizePolynomial(polynomial, min_x, max_x, &optimal_x, &optimal_value);
-  EXPECT_EQ(optimal_x, 3.0/2.0);
-  EXPECT_EQ(optimal_value, -1.0/4.0);
+  EXPECT_EQ(optimal_x, 3.0 / 2.0);
+  EXPECT_EQ(optimal_value, -1.0 / 4.0);
 
   min_x = -2.0;
   max_x = 1.0;
@@ -402,7 +402,6 @@
   EXPECT_NEAR((true_polynomial - polynomial).norm(), 0.0, 1e-14);
 }
 
-
 TEST(Polynomial, CubicInterpolatingPolynomialFromValues) {
   // p(x) = x^3 + 2x^2 + 3x + 2
   Vector true_polynomial(4);
diff --git a/internal/ceres/preconditioner.cc b/internal/ceres/preconditioner.cc
index f98374e..69ba04d 100644
--- a/internal/ceres/preconditioner.cc
+++ b/internal/ceres/preconditioner.cc
@@ -29,13 +29,13 @@
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
 #include "ceres/preconditioner.h"
+
 #include "glog/logging.h"
 
 namespace ceres {
 namespace internal {
 
-Preconditioner::~Preconditioner() {
-}
+Preconditioner::~Preconditioner() {}
 
 PreconditionerType Preconditioner::PreconditionerForZeroEBlocks(
     PreconditionerType preconditioner_type) {
@@ -53,8 +53,7 @@
   CHECK(matrix != nullptr);
 }
 
-SparseMatrixPreconditionerWrapper::~SparseMatrixPreconditionerWrapper() {
-}
+SparseMatrixPreconditionerWrapper::~SparseMatrixPreconditionerWrapper() {}
 
 bool SparseMatrixPreconditionerWrapper::UpdateImpl(const SparseMatrix& A,
                                                    const double* D) {
@@ -66,7 +65,7 @@
   matrix_->RightMultiply(x, y);
 }
 
-int  SparseMatrixPreconditionerWrapper::num_rows() const {
+int SparseMatrixPreconditionerWrapper::num_rows() const {
   return matrix_->num_rows();
 }
 
diff --git a/internal/ceres/preconditioner.h b/internal/ceres/preconditioner.h
index 476697d..dd843b0 100644
--- a/internal/ceres/preconditioner.h
+++ b/internal/ceres/preconditioner.h
@@ -32,9 +32,11 @@
 #define CERES_INTERNAL_PRECONDITIONER_H_
 
 #include <vector>
+
 #include "ceres/casts.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/context_impl.h"
+#include "ceres/internal/port.h"
 #include "ceres/linear_operator.h"
 #include "ceres/sparse_matrix.h"
 #include "ceres/types.h"
@@ -45,12 +47,13 @@
 class BlockSparseMatrix;
 class SparseMatrix;
 
-class Preconditioner : public LinearOperator {
+class CERES_EXPORT_INTERNAL Preconditioner : public LinearOperator {
  public:
   struct Options {
     PreconditionerType type = JACOBI;
     VisibilityClusteringType visibility_clustering_type = CANONICAL_VIEWS;
-    SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type = SUITE_SPARSE;
+    SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type =
+        SUITE_SPARSE;
 
     // When using the subset preconditioner, all row blocks starting
     // from this row block are used to construct the preconditioner.
@@ -131,15 +134,13 @@
   // LeftMultiply and num_cols are just calls to RightMultiply and
   // num_rows respectively. Update() must be called before
   // RightMultiply can be called.
-  virtual void RightMultiply(const double* x, double* y) const = 0;
-  virtual void LeftMultiply(const double* x, double* y) const {
+  void RightMultiply(const double* x, double* y) const override = 0;
+  void LeftMultiply(const double* x, double* y) const override {
     return RightMultiply(x, y);
   }
 
-  virtual int num_rows() const = 0;
-  virtual int num_cols() const {
-    return num_rows();
-  }
+  int num_rows() const override = 0;
+  int num_cols() const override { return num_rows(); }
 };
 
 // This templated subclass of Preconditioner serves as a base class for
@@ -149,7 +150,7 @@
 class TypedPreconditioner : public Preconditioner {
  public:
   virtual ~TypedPreconditioner() {}
-  virtual bool Update(const LinearOperator& A, const double* D) {
+  bool Update(const LinearOperator& A, const double* D) final {
     return UpdateImpl(*down_cast<const MatrixType*>(&A), D);
   }
 
@@ -159,9 +160,11 @@
 
 // Preconditioners that depend on access to the low level structure
 // of a SparseMatrix.
-typedef TypedPreconditioner<SparseMatrix>              SparseMatrixPreconditioner;               // NOLINT
-typedef TypedPreconditioner<BlockSparseMatrix>         BlockSparseMatrixPreconditioner;          // NOLINT
-typedef TypedPreconditioner<CompressedRowSparseMatrix> CompressedRowSparseMatrixPreconditioner;  // NOLINT
+// clang-format off
+typedef TypedPreconditioner<SparseMatrix>              SparseMatrixPreconditioner;
+typedef TypedPreconditioner<BlockSparseMatrix>         BlockSparseMatrixPreconditioner;
+typedef TypedPreconditioner<CompressedRowSparseMatrix> CompressedRowSparseMatrixPreconditioner;
+// clang-format on
 
 // Wrap a SparseMatrix object as a preconditioner.
 class SparseMatrixPreconditionerWrapper : public SparseMatrixPreconditioner {
diff --git a/internal/ceres/preprocessor.cc b/internal/ceres/preprocessor.cc
index 0221914..6a67d38 100644
--- a/internal/ceres/preprocessor.cc
+++ b/internal/ceres/preprocessor.cc
@@ -28,11 +28,12 @@
 //
 // Author: sameragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/preprocessor.h"
+
 #include "ceres/callbacks.h"
 #include "ceres/gradient_checking_cost_function.h"
 #include "ceres/line_search_preprocessor.h"
 #include "ceres/parallel_for.h"
-#include "ceres/preprocessor.h"
 #include "ceres/problem_impl.h"
 #include "ceres/solver.h"
 #include "ceres/trust_region_preprocessor.h"
@@ -53,17 +54,15 @@
   return NULL;
 }
 
-Preprocessor::~Preprocessor() {
-}
+Preprocessor::~Preprocessor() {}
 
 void ChangeNumThreadsIfNeeded(Solver::Options* options) {
   const int num_threads_available = MaxNumThreadsAvailable();
   if (options->num_threads > num_threads_available) {
-    LOG(WARNING)
-        << "Specified options.num_threads: " << options->num_threads
-        << " exceeds maximum available from the threading model Ceres "
-        << "was compiled with: " << num_threads_available
-        << ".  Bounding to maximum number available.";
+    LOG(WARNING) << "Specified options.num_threads: " << options->num_threads
+                 << " exceeds maximum available from the threading model Ceres "
+                 << "was compiled with: " << num_threads_available
+                 << ".  Bounding to maximum number available.";
     options->num_threads = num_threads_available;
   }
 }
@@ -83,16 +82,15 @@
   minimizer_options.evaluator = pp->evaluator;
 
   if (options.logging_type != SILENT) {
-    pp->logging_callback.reset(
-        new LoggingCallback(options.minimizer_type,
-                            options.minimizer_progress_to_stdout));
+    pp->logging_callback.reset(new LoggingCallback(
+        options.minimizer_type, options.minimizer_progress_to_stdout));
     minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
                                        pp->logging_callback.get());
   }
 
   if (options.update_state_every_iteration) {
     pp->state_updating_callback.reset(
-      new StateUpdatingCallback(program, reduced_parameters));
+        new StateUpdatingCallback(program, reduced_parameters));
     // This must get pushed to the front of the callbacks so that it
     // is run before any of the user callbacks.
     minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
diff --git a/internal/ceres/preprocessor.h b/internal/ceres/preprocessor.h
index 99bd6c0..ec56c6e 100644
--- a/internal/ceres/preprocessor.h
+++ b/internal/ceres/preprocessor.h
@@ -67,7 +67,7 @@
 //
 // The output of the Preprocessor is stored in a PreprocessedProblem
 // object.
-class Preprocessor {
+class CERES_EXPORT_INTERNAL Preprocessor {
  public:
   // Factory.
   static Preprocessor* Create(MinimizerType minimizer_type);
@@ -80,9 +80,7 @@
 // A PreprocessedProblem is the result of running the Preprocessor on
 // a Problem and Solver::Options object.
 struct PreprocessedProblem {
-  PreprocessedProblem()
-      : fixed_cost(0.0) {
-  }
+  PreprocessedProblem() : fixed_cost(0.0) {}
 
   std::string error;
   Solver::Options options;
diff --git a/internal/ceres/problem.cc b/internal/ceres/problem.cc
index 6939b46..f3ffd54 100644
--- a/internal/ceres/problem.cc
+++ b/internal/ceres/problem.cc
@@ -32,6 +32,7 @@
 #include "ceres/problem.h"
 
 #include <vector>
+
 #include "ceres/crs_matrix.h"
 #include "ceres/problem_impl.h"
 
@@ -39,92 +40,90 @@
 
 using std::vector;
 
-Problem::Problem() : problem_impl_(new internal::ProblemImpl) {}
+Problem::Problem() : impl_(new internal::ProblemImpl) {}
 Problem::Problem(const Problem::Options& options)
-    : problem_impl_(new internal::ProblemImpl(options)) {}
+    : impl_(new internal::ProblemImpl(options)) {}
+// Not inline defaulted in declaration due to use of std::unique_ptr.
+Problem::Problem(Problem&&) = default;
+Problem& Problem::operator=(Problem&&) = default;
 Problem::~Problem() {}
 
 ResidualBlockId Problem::AddResidualBlock(
     CostFunction* cost_function,
     LossFunction* loss_function,
     const vector<double*>& parameter_blocks) {
-  return problem_impl_->AddResidualBlock(
-      cost_function,
-      loss_function,
-      parameter_blocks.data(),
-      static_cast<int>(parameter_blocks.size()));
+  return impl_->AddResidualBlock(cost_function,
+                                 loss_function,
+                                 parameter_blocks.data(),
+                                 static_cast<int>(parameter_blocks.size()));
 }
 
-ResidualBlockId Problem::AddResidualBlock(
-    CostFunction* cost_function,
-    LossFunction* loss_function,
-    double* const* const parameter_blocks,
-    int num_parameter_blocks) {
-  return problem_impl_->AddResidualBlock(cost_function,
-                                         loss_function,
-                                         parameter_blocks,
-                                         num_parameter_blocks);
+ResidualBlockId Problem::AddResidualBlock(CostFunction* cost_function,
+                                          LossFunction* loss_function,
+                                          double* const* const parameter_blocks,
+                                          int num_parameter_blocks) {
+  return impl_->AddResidualBlock(
+      cost_function, loss_function, parameter_blocks, num_parameter_blocks);
 }
 
 void Problem::AddParameterBlock(double* values, int size) {
-  problem_impl_->AddParameterBlock(values, size);
+  impl_->AddParameterBlock(values, size);
 }
 
 void Problem::AddParameterBlock(double* values,
                                 int size,
                                 LocalParameterization* local_parameterization) {
-  problem_impl_->AddParameterBlock(values, size, local_parameterization);
+  impl_->AddParameterBlock(values, size, local_parameterization);
 }
 
 void Problem::RemoveResidualBlock(ResidualBlockId residual_block) {
-  problem_impl_->RemoveResidualBlock(residual_block);
+  impl_->RemoveResidualBlock(residual_block);
 }
 
-void Problem::RemoveParameterBlock(double* values) {
-  problem_impl_->RemoveParameterBlock(values);
+void Problem::RemoveParameterBlock(const double* values) {
+  impl_->RemoveParameterBlock(values);
 }
 
-void Problem::SetParameterBlockConstant(double* values) {
-  problem_impl_->SetParameterBlockConstant(values);
+void Problem::SetParameterBlockConstant(const double* values) {
+  impl_->SetParameterBlockConstant(values);
 }
 
 void Problem::SetParameterBlockVariable(double* values) {
-  problem_impl_->SetParameterBlockVariable(values);
+  impl_->SetParameterBlockVariable(values);
 }
 
-bool Problem::IsParameterBlockConstant(double* values) const {
-  return problem_impl_->IsParameterBlockConstant(values);
+bool Problem::IsParameterBlockConstant(const double* values) const {
+  return impl_->IsParameterBlockConstant(values);
 }
 
 void Problem::SetParameterization(
-    double* values,
-    LocalParameterization* local_parameterization) {
-  problem_impl_->SetParameterization(values, local_parameterization);
+    double* values, LocalParameterization* local_parameterization) {
+  impl_->SetParameterization(values, local_parameterization);
 }
 
 const LocalParameterization* Problem::GetParameterization(
-    double* values) const {
-  return problem_impl_->GetParameterization(values);
+    const double* values) const {
+  return impl_->GetParameterization(values);
 }
 
 void Problem::SetParameterLowerBound(double* values,
                                      int index,
                                      double lower_bound) {
-  problem_impl_->SetParameterLowerBound(values, index, lower_bound);
+  impl_->SetParameterLowerBound(values, index, lower_bound);
 }
 
 void Problem::SetParameterUpperBound(double* values,
                                      int index,
                                      double upper_bound) {
-  problem_impl_->SetParameterUpperBound(values, index, upper_bound);
+  impl_->SetParameterUpperBound(values, index, upper_bound);
 }
 
-double Problem::GetParameterUpperBound(double* values, int index) const {
-  return problem_impl_->GetParameterUpperBound(values, index);
+double Problem::GetParameterUpperBound(const double* values, int index) const {
+  return impl_->GetParameterUpperBound(values, index);
 }
 
-double Problem::GetParameterLowerBound(double* values, int index) const {
-  return problem_impl_->GetParameterLowerBound(values, index);
+double Problem::GetParameterLowerBound(const double* values, int index) const {
+  return impl_->GetParameterLowerBound(values, index);
 }
 
 bool Problem::Evaluate(const EvaluateOptions& evaluate_options,
@@ -132,72 +131,84 @@
                        vector<double>* residuals,
                        vector<double>* gradient,
                        CRSMatrix* jacobian) {
-  return problem_impl_->Evaluate(evaluate_options,
-                                 cost,
-                                 residuals,
-                                 gradient,
-                                 jacobian);
+  return impl_->Evaluate(evaluate_options, cost, residuals, gradient, jacobian);
 }
 
-int Problem::NumParameterBlocks() const {
-  return problem_impl_->NumParameterBlocks();
+bool Problem::EvaluateResidualBlock(ResidualBlockId residual_block_id,
+                                    bool apply_loss_function,
+                                    double* cost,
+                                    double* residuals,
+                                    double** jacobians) const {
+  return impl_->EvaluateResidualBlock(residual_block_id,
+                                      apply_loss_function,
+                                      /* new_point = */ true,
+                                      cost,
+                                      residuals,
+                                      jacobians);
 }
 
-int Problem::NumParameters() const {
-  return problem_impl_->NumParameters();
+bool Problem::EvaluateResidualBlockAssumingParametersUnchanged(
+    ResidualBlockId residual_block_id,
+    bool apply_loss_function,
+    double* cost,
+    double* residuals,
+    double** jacobians) const {
+  return impl_->EvaluateResidualBlock(residual_block_id,
+                                      apply_loss_function,
+                                      /* new_point = */ false,
+                                      cost,
+                                      residuals,
+                                      jacobians);
 }
 
-int Problem::NumResidualBlocks() const {
-  return problem_impl_->NumResidualBlocks();
-}
+int Problem::NumParameterBlocks() const { return impl_->NumParameterBlocks(); }
 
-int Problem::NumResiduals() const {
-  return problem_impl_->NumResiduals();
-}
+int Problem::NumParameters() const { return impl_->NumParameters(); }
+
+int Problem::NumResidualBlocks() const { return impl_->NumResidualBlocks(); }
+
+int Problem::NumResiduals() const { return impl_->NumResiduals(); }
 
 int Problem::ParameterBlockSize(const double* parameter_block) const {
-  return problem_impl_->ParameterBlockSize(parameter_block);
+  return impl_->ParameterBlockSize(parameter_block);
 }
 
 int Problem::ParameterBlockLocalSize(const double* parameter_block) const {
-  return problem_impl_->ParameterBlockLocalSize(parameter_block);
+  return impl_->ParameterBlockLocalSize(parameter_block);
 }
 
 bool Problem::HasParameterBlock(const double* values) const {
-  return problem_impl_->HasParameterBlock(values);
+  return impl_->HasParameterBlock(values);
 }
 
 void Problem::GetParameterBlocks(vector<double*>* parameter_blocks) const {
-  problem_impl_->GetParameterBlocks(parameter_blocks);
+  impl_->GetParameterBlocks(parameter_blocks);
 }
 
 void Problem::GetResidualBlocks(
     vector<ResidualBlockId>* residual_blocks) const {
-  problem_impl_->GetResidualBlocks(residual_blocks);
+  impl_->GetResidualBlocks(residual_blocks);
 }
 
 void Problem::GetParameterBlocksForResidualBlock(
     const ResidualBlockId residual_block,
     vector<double*>* parameter_blocks) const {
-  problem_impl_->GetParameterBlocksForResidualBlock(residual_block,
-                                                    parameter_blocks);
+  impl_->GetParameterBlocksForResidualBlock(residual_block, parameter_blocks);
 }
 
 const CostFunction* Problem::GetCostFunctionForResidualBlock(
     const ResidualBlockId residual_block) const {
-  return problem_impl_->GetCostFunctionForResidualBlock(residual_block);
+  return impl_->GetCostFunctionForResidualBlock(residual_block);
 }
 
 const LossFunction* Problem::GetLossFunctionForResidualBlock(
     const ResidualBlockId residual_block) const {
-  return problem_impl_->GetLossFunctionForResidualBlock(residual_block);
+  return impl_->GetLossFunctionForResidualBlock(residual_block);
 }
 
 void Problem::GetResidualBlocksForParameterBlock(
-    const double* values,
-    vector<ResidualBlockId>* residual_blocks) const {
-  problem_impl_->GetResidualBlocksForParameterBlock(values,
-                                                    residual_blocks);
+    const double* values, vector<ResidualBlockId>* residual_blocks) const {
+  impl_->GetResidualBlocksForParameterBlock(values, residual_blocks);
 }
 
 }  // namespace ceres
diff --git a/internal/ceres/problem_impl.cc b/internal/ceres/problem_impl.cc
index 40d5aa2..3155bc3 100644
--- a/internal/ceres/problem_impl.cc
+++ b/internal/ceres/problem_impl.cc
@@ -1,5 +1,5 @@
 // Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2015 Google Inc. All rights reserved.
+// Copyright 2019 Google Inc. All rights reserved.
 // http://ceres-solver.org/
 //
 // Redistribution and use in source and binary forms, with or without
@@ -47,7 +47,9 @@
 #include "ceres/context_impl.h"
 #include "ceres/cost_function.h"
 #include "ceres/crs_matrix.h"
+#include "ceres/evaluation_callback.h"
 #include "ceres/evaluator.h"
+#include "ceres/internal/fixed_array.h"
 #include "ceres/internal/port.h"
 #include "ceres/loss_function.h"
 #include "ceres/map_util.h"
@@ -70,21 +72,19 @@
 namespace {
 // Returns true if two regions of memory, a and b, with sizes size_a and size_b
 // respectively, overlap.
-bool RegionsAlias(const double* a, int size_a,
-                  const double* b, int size_b) {
-  return (a < b) ? b < (a + size_a)
-                 : a < (b + size_b);
+bool RegionsAlias(const double* a, int size_a, const double* b, int size_b) {
+  return (a < b) ? b < (a + size_a) : a < (b + size_b);
 }
 
 void CheckForNoAliasing(double* existing_block,
                         int existing_block_size,
                         double* new_block,
                         int new_block_size) {
-  CHECK(!RegionsAlias(existing_block, existing_block_size,
-                      new_block, new_block_size))
+  CHECK(!RegionsAlias(
+      existing_block, existing_block_size, new_block, new_block_size))
       << "Aliasing detected between existing parameter block at memory "
-      << "location " << existing_block
-      << " and has size " << existing_block_size << " with new parameter "
+      << "location " << existing_block << " and has size "
+      << existing_block_size << " with new parameter "
       << "block that has memory address " << new_block << " and would have "
       << "size " << new_block_size << ".";
 }
@@ -113,7 +113,7 @@
 void InitializeContext(Context* context,
                        ContextImpl** context_impl,
                        bool* context_impl_owned) {
-  if (context == NULL) {
+  if (context == nullptr) {
     *context_impl_owned = true;
     *context_impl = new ContextImpl;
   } else {
@@ -126,8 +126,8 @@
 
 ParameterBlock* ProblemImpl::InternalAddParameterBlock(double* values,
                                                        int size) {
-  CHECK(values != NULL) << "Null pointer passed to AddParameterBlock "
-                        << "for a parameter with size " << size;
+  CHECK(values != nullptr) << "Null pointer passed to AddParameterBlock "
+                           << "for a parameter with size " << size;
 
   // Ignore the request if there is a block for the given pointer already.
   ParameterMap::iterator it = parameter_block_map_.find(values);
@@ -137,8 +137,7 @@
       CHECK(size == existing_size)
           << "Tried adding a parameter block with the same double pointer, "
           << values << ", twice, but with different block sizes. Original "
-          << "size was " << existing_size << " but new size is "
-          << size;
+          << "size was " << existing_size << " but new size is " << size;
     }
     return it->second;
   }
@@ -153,18 +152,13 @@
       if (lb != parameter_block_map_.begin()) {
         ParameterMap::iterator previous = lb;
         --previous;
-        CheckForNoAliasing(previous->first,
-                           previous->second->Size(),
-                           values,
-                           size);
+        CheckForNoAliasing(
+            previous->first, previous->second->Size(), values, size);
       }
 
       // If lb is not off the end, check lb for aliasing.
       if (lb != parameter_block_map_.end()) {
-        CheckForNoAliasing(lb->first,
-                           lb->second->Size(),
-                           values,
-                           size);
+        CheckForNoAliasing(lb->first, lb->second->Size(), values, size);
       }
     }
   }
@@ -194,8 +188,8 @@
     const int num_parameter_blocks_for_residual =
         residual_block->NumParameterBlocks();
     for (int i = 0; i < num_parameter_blocks_for_residual; ++i) {
-      residual_block->parameter_blocks()[i]
-          ->RemoveResidualBlock(residual_block);
+      residual_block->parameter_blocks()[i]->RemoveResidualBlock(
+          residual_block);
     }
 
     ResidualBlockSet::iterator it = residual_block_set_.find(residual_block);
@@ -222,7 +216,7 @@
   LossFunction* loss_function =
       const_cast<LossFunction*>(residual_block->loss_function());
   if (options_.loss_function_ownership == TAKE_OWNERSHIP &&
-      loss_function != NULL) {
+      loss_function != nullptr) {
     DecrementValueOrDeleteKey(loss_function, &loss_function_ref_count_);
   }
 
@@ -236,7 +230,7 @@
 // without doing a full scan.
 void ProblemImpl::DeleteBlock(ParameterBlock* parameter_block) {
   if (options_.local_parameterization_ownership == TAKE_OWNERSHIP &&
-      parameter_block->local_parameterization() != NULL) {
+      parameter_block->local_parameterization() != nullptr) {
     local_parameterizations_to_delete_.push_back(
         parameter_block->mutable_local_parameterization());
   }
@@ -245,14 +239,13 @@
 }
 
 ProblemImpl::ProblemImpl()
-    : options_(Problem::Options()),
-      program_(new internal::Program) {
+    : options_(Problem::Options()), program_(new internal::Program) {
   InitializeContext(options_.context, &context_impl_, &context_impl_owned_);
 }
 
 ProblemImpl::ProblemImpl(const Problem::Options& options)
-    : options_(options),
-      program_(new internal::Program) {
+    : options_(options), program_(new internal::Program) {
+  program_->evaluation_callback_ = options.evaluation_callback;
   InitializeContext(options_.context, &context_impl_, &context_impl_owned_);
 }
 
@@ -285,13 +278,12 @@
 }
 
 ResidualBlockId ProblemImpl::AddResidualBlock(
-      CostFunction* cost_function,
-      LossFunction* loss_function,
-      double* const* const parameter_blocks,
-      int num_parameter_blocks) {
+    CostFunction* cost_function,
+    LossFunction* loss_function,
+    double* const* const parameter_blocks,
+    int num_parameter_blocks) {
   CHECK(cost_function != nullptr);
-  CHECK_EQ(num_parameter_blocks,
-           cost_function->parameter_block_sizes().size());
+  CHECK_EQ(num_parameter_blocks, cost_function->parameter_block_sizes().size());
 
   // Check the sizes match.
   const vector<int32_t>& parameter_block_sizes =
@@ -308,8 +300,8 @@
     sort(sorted_parameter_blocks.begin(), sorted_parameter_blocks.end());
     const bool has_duplicate_items =
         (std::adjacent_find(sorted_parameter_blocks.begin(),
-                            sorted_parameter_blocks.end())
-         != sorted_parameter_blocks.end());
+                            sorted_parameter_blocks.end()) !=
+         sorted_parameter_blocks.end());
     if (has_duplicate_items) {
       string blocks;
       for (int i = 0; i < num_parameter_blocks; ++i) {
@@ -317,17 +309,16 @@
       }
 
       LOG(FATAL) << "Duplicate parameter blocks in a residual parameter "
-                 << "are not allowed. Parameter block pointers: ["
-                 << blocks << "]";
+                 << "are not allowed. Parameter block pointers: [" << blocks
+                 << "]";
     }
   }
 
   // Add parameter blocks and convert the double*'s to parameter blocks.
   vector<ParameterBlock*> parameter_block_ptrs(num_parameter_blocks);
   for (int i = 0; i < num_parameter_blocks; ++i) {
-    parameter_block_ptrs[i] =
-        InternalAddParameterBlock(parameter_blocks[i],
-                                  parameter_block_sizes[i]);
+    parameter_block_ptrs[i] = InternalAddParameterBlock(
+        parameter_blocks[i], parameter_block_sizes[i]);
   }
 
   if (!options_.disable_all_safety_checks) {
@@ -336,8 +327,8 @@
     for (int i = 0; i < parameter_block_ptrs.size(); ++i) {
       CHECK_EQ(cost_function->parameter_block_sizes()[i],
                parameter_block_ptrs[i]->Size())
-          << "The cost function expects parameter block " << i
-          << " of size " << cost_function->parameter_block_sizes()[i]
+          << "The cost function expects parameter block " << i << " of size "
+          << cost_function->parameter_block_sizes()[i]
           << " but was given a block of size "
           << parameter_block_ptrs[i]->Size();
     }
@@ -370,7 +361,7 @@
   }
 
   if (options_.loss_function_ownership == TAKE_OWNERSHIP &&
-      loss_function != NULL) {
+      loss_function != nullptr) {
     ++loss_function_ref_count_[loss_function];
   }
 
@@ -382,12 +373,9 @@
 }
 
 void ProblemImpl::AddParameterBlock(
-    double* values,
-    int size,
-    LocalParameterization* local_parameterization) {
-  ParameterBlock* parameter_block =
-      InternalAddParameterBlock(values, size);
-  if (local_parameterization != NULL) {
+    double* values, int size, LocalParameterization* local_parameterization) {
+  ParameterBlock* parameter_block = InternalAddParameterBlock(values, size);
+  if (local_parameterization != nullptr) {
     parameter_block->SetParameterization(local_parameterization);
   }
 }
@@ -396,13 +384,12 @@
 // This is done in constant time by moving an element from the end of the
 // vector over the element to remove, then popping the last element. It
 // destroys the ordering in the interest of speed.
-template<typename Block>
+template <typename Block>
 void ProblemImpl::DeleteBlockInVector(vector<Block*>* mutable_blocks,
                                       Block* block_to_remove) {
   CHECK_EQ((*mutable_blocks)[block_to_remove->index()], block_to_remove)
       << "You found a Ceres bug! \n"
-      << "Block requested: "
-      << block_to_remove->ToString() << "\n"
+      << "Block requested: " << block_to_remove->ToString() << "\n"
       << "Block present: "
       << (*mutable_blocks)[block_to_remove->index()]->ToString();
 
@@ -424,21 +411,20 @@
   CHECK(residual_block != nullptr);
 
   // Verify that residual_block identifies a residual in the current problem.
-  const string residual_not_found_message =
-      StringPrintf("Residual block to remove: %p not found. This usually means "
-                   "one of three things have happened:\n"
-                   " 1) residual_block is uninitialised and points to a random "
-                   "area in memory.\n"
-                   " 2) residual_block represented a residual that was added to"
-                   " the problem, but referred to a parameter block which has "
-                   "since been removed, which removes all residuals which "
-                   "depend on that parameter block, and was thus removed.\n"
-                   " 3) residual_block referred to a residual that has already "
-                   "been removed from the problem (by the user).",
-                   residual_block);
+  const string residual_not_found_message = StringPrintf(
+      "Residual block to remove: %p not found. This usually means "
+      "one of three things have happened:\n"
+      " 1) residual_block is uninitialised and points to a random "
+      "area in memory.\n"
+      " 2) residual_block represented a residual that was added to"
+      " the problem, but referred to a parameter block which has "
+      "since been removed, which removes all residuals which "
+      "depend on that parameter block, and was thus removed.\n"
+      " 3) residual_block referred to a residual that has already "
+      "been removed from the problem (by the user).",
+      residual_block);
   if (options_.enable_fast_removal) {
-    CHECK(residual_block_set_.find(residual_block) !=
-          residual_block_set_.end())
+    CHECK(residual_block_set_.find(residual_block) != residual_block_set_.end())
         << residual_not_found_message;
   } else {
     // Perform a full search over all current residuals.
@@ -451,10 +437,10 @@
   InternalRemoveResidualBlock(residual_block);
 }
 
-void ProblemImpl::RemoveParameterBlock(double* values) {
-  ParameterBlock* parameter_block =
-      FindWithDefault(parameter_block_map_, values, NULL);
-  if (parameter_block == NULL) {
+void ProblemImpl::RemoveParameterBlock(const double* values) {
+  ParameterBlock* parameter_block = FindWithDefault(
+      parameter_block_map_, const_cast<double*>(values), nullptr);
+  if (parameter_block == nullptr) {
     LOG(FATAL) << "Parameter block not found: " << values
                << ". You must add the parameter block to the problem before "
                << "it can be removed.";
@@ -489,10 +475,10 @@
   DeleteBlockInVector(program_->mutable_parameter_blocks(), parameter_block);
 }
 
-void ProblemImpl::SetParameterBlockConstant(double* values) {
-  ParameterBlock* parameter_block =
-      FindWithDefault(parameter_block_map_, values, NULL);
-  if (parameter_block == NULL) {
+void ProblemImpl::SetParameterBlockConstant(const double* values) {
+  ParameterBlock* parameter_block = FindWithDefault(
+      parameter_block_map_, const_cast<double*>(values), nullptr);
+  if (parameter_block == nullptr) {
     LOG(FATAL) << "Parameter block not found: " << values
                << ". You must add the parameter block to the problem before "
                << "it can be set constant.";
@@ -501,20 +487,19 @@
   parameter_block->SetConstant();
 }
 
-bool ProblemImpl::IsParameterBlockConstant(double* values) const {
-  const ParameterBlock* parameter_block =
-      FindWithDefault(parameter_block_map_, values, NULL);
-  CHECK(parameter_block != NULL)
-    << "Parameter block not found: " << values << ". You must add the "
-    << "parameter block to the problem before it can be queried.";
-
-  return parameter_block->IsSetConstantByUser();
+bool ProblemImpl::IsParameterBlockConstant(const double* values) const {
+  const ParameterBlock* parameter_block = FindWithDefault(
+      parameter_block_map_, const_cast<double*>(values), nullptr);
+  CHECK(parameter_block != nullptr)
+      << "Parameter block not found: " << values << ". You must add the "
+      << "parameter block to the problem before it can be queried.";
+  return parameter_block->IsConstant();
 }
 
 void ProblemImpl::SetParameterBlockVariable(double* values) {
   ParameterBlock* parameter_block =
-      FindWithDefault(parameter_block_map_, values, NULL);
-  if (parameter_block == NULL) {
+      FindWithDefault(parameter_block_map_, values, nullptr);
+  if (parameter_block == nullptr) {
     LOG(FATAL) << "Parameter block not found: " << values
                << ". You must add the parameter block to the problem before "
                << "it can be set varying.";
@@ -524,24 +509,32 @@
 }
 
 void ProblemImpl::SetParameterization(
-    double* values,
-    LocalParameterization* local_parameterization) {
+    double* values, LocalParameterization* local_parameterization) {
   ParameterBlock* parameter_block =
-      FindWithDefault(parameter_block_map_, values, NULL);
-  if (parameter_block == NULL) {
+      FindWithDefault(parameter_block_map_, values, nullptr);
+  if (parameter_block == nullptr) {
     LOG(FATAL) << "Parameter block not found: " << values
                << ". You must add the parameter block to the problem before "
                << "you can set its local parameterization.";
   }
 
+  // If the parameter block already has a local parameterization and
+  // we are to take ownership of local parameterizations, then add it
+  // to local_parameterizations_to_delete_ for eventual deletion.
+  if (parameter_block->local_parameterization_ &&
+      options_.local_parameterization_ownership == TAKE_OWNERSHIP) {
+    local_parameterizations_to_delete_.push_back(
+        parameter_block->local_parameterization_);
+  }
+
   parameter_block->SetParameterization(local_parameterization);
 }
 
 const LocalParameterization* ProblemImpl::GetParameterization(
-    double* values) const {
-  ParameterBlock* parameter_block =
-      FindWithDefault(parameter_block_map_, values, NULL);
-  if (parameter_block == NULL) {
+    const double* values) const {
+  ParameterBlock* parameter_block = FindWithDefault(
+      parameter_block_map_, const_cast<double*>(values), nullptr);
+  if (parameter_block == nullptr) {
     LOG(FATAL) << "Parameter block not found: " << values
                << ". You must add the parameter block to the problem before "
                << "you can get its local parameterization.";
@@ -554,8 +547,8 @@
                                          int index,
                                          double lower_bound) {
   ParameterBlock* parameter_block =
-      FindWithDefault(parameter_block_map_, values, NULL);
-  if (parameter_block == NULL) {
+      FindWithDefault(parameter_block_map_, values, nullptr);
+  if (parameter_block == nullptr) {
     LOG(FATAL) << "Parameter block not found: " << values
                << ". You must add the parameter block to the problem before "
                << "you can set a lower bound on one of its components.";
@@ -568,8 +561,8 @@
                                          int index,
                                          double upper_bound) {
   ParameterBlock* parameter_block =
-      FindWithDefault(parameter_block_map_, values, NULL);
-  if (parameter_block == NULL) {
+      FindWithDefault(parameter_block_map_, values, nullptr);
+  if (parameter_block == nullptr) {
     LOG(FATAL) << "Parameter block not found: " << values
                << ". You must add the parameter block to the problem before "
                << "you can set an upper bound on one of its components.";
@@ -577,10 +570,11 @@
   parameter_block->SetUpperBound(index, upper_bound);
 }
 
-double ProblemImpl::GetParameterLowerBound(double* values, int index) const {
-  ParameterBlock* parameter_block =
-      FindWithDefault(parameter_block_map_, values, NULL);
-  if (parameter_block == NULL) {
+double ProblemImpl::GetParameterLowerBound(const double* values,
+                                           int index) const {
+  ParameterBlock* parameter_block = FindWithDefault(
+      parameter_block_map_, const_cast<double*>(values), nullptr);
+  if (parameter_block == nullptr) {
     LOG(FATAL) << "Parameter block not found: " << values
                << ". You must add the parameter block to the problem before "
                << "you can get the lower bound on one of its components.";
@@ -588,10 +582,11 @@
   return parameter_block->LowerBound(index);
 }
 
-double ProblemImpl::GetParameterUpperBound(double* values, int index) const {
-  ParameterBlock* parameter_block =
-      FindWithDefault(parameter_block_map_, values, NULL);
-  if (parameter_block == NULL) {
+double ProblemImpl::GetParameterUpperBound(const double* values,
+                                           int index) const {
+  ParameterBlock* parameter_block = FindWithDefault(
+      parameter_block_map_, const_cast<double*>(values), nullptr);
+  if (parameter_block == nullptr) {
     LOG(FATAL) << "Parameter block not found: " << values
                << ". You must add the parameter block to the problem before "
                << "you can set an upper bound on one of its components.";
@@ -604,11 +599,8 @@
                            vector<double>* residuals,
                            vector<double>* gradient,
                            CRSMatrix* jacobian) {
-  if (cost == NULL &&
-      residuals == NULL &&
-      gradient == NULL &&
-      jacobian == NULL) {
-    LOG(INFO) << "Nothing to do.";
+  if (cost == nullptr && residuals == nullptr && gradient == nullptr &&
+      jacobian == nullptr) {
     return true;
   }
 
@@ -617,7 +609,8 @@
   Program program;
   *program.mutable_residual_blocks() =
       ((evaluate_options.residual_blocks.size() > 0)
-       ? evaluate_options.residual_blocks : program_->residual_blocks());
+           ? evaluate_options.residual_blocks
+           : program_->residual_blocks());
 
   const vector<double*>& parameter_block_ptrs =
       evaluate_options.parameter_blocks;
@@ -638,10 +631,9 @@
     // 1. Convert double* into ParameterBlock*
     parameter_blocks.resize(parameter_block_ptrs.size());
     for (int i = 0; i < parameter_block_ptrs.size(); ++i) {
-      parameter_blocks[i] = FindWithDefault(parameter_block_map_,
-                                            parameter_block_ptrs[i],
-                                            NULL);
-      if (parameter_blocks[i] == NULL) {
+      parameter_blocks[i] = FindWithDefault(
+          parameter_block_map_, parameter_block_ptrs[i], nullptr);
+      if (parameter_blocks[i] == nullptr) {
         LOG(FATAL) << "No known parameter block for "
                    << "Problem::Evaluate::Options.parameter_blocks[" << i << "]"
                    << " = " << parameter_block_ptrs[i];
@@ -693,10 +685,12 @@
   // type of linear solver being used.
   evaluator_options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
 #ifdef CERES_NO_THREADS
-  LOG_IF(WARNING, evaluate_options.num_threads > 1)
-      << "No threading support is compiled into this binary; "
-      << "only evaluate_options.num_threads = 1 is supported. Switching "
-      << "to single threaded mode.";
+  if (evaluate_options.num_threads > 1) {
+    LOG(WARNING)
+        << "No threading support is compiled into this binary; "
+        << "only evaluate_options.num_threads = 1 is supported. Switching "
+        << "to single threaded mode.";
+  }
   evaluator_options.num_threads = 1;
 #else
   evaluator_options.num_threads = evaluate_options.num_threads;
@@ -705,22 +699,23 @@
   // The main thread also does work so we only need to launch num_threads - 1.
   context_impl_->EnsureMinimumThreads(evaluator_options.num_threads - 1);
   evaluator_options.context = context_impl_;
-
+  evaluator_options.evaluation_callback =
+      program_->mutable_evaluation_callback();
   std::unique_ptr<Evaluator> evaluator(
       new ProgramEvaluator<ScratchEvaluatePreparer,
                            CompressedRowJacobianWriter>(evaluator_options,
                                                         &program));
 
-  if (residuals !=NULL) {
+  if (residuals != nullptr) {
     residuals->resize(evaluator->NumResiduals());
   }
 
-  if (gradient != NULL) {
+  if (gradient != nullptr) {
     gradient->resize(evaluator->NumEffectiveParameters());
   }
 
   std::unique_ptr<CompressedRowSparseMatrix> tmp_jacobian;
-  if (jacobian != NULL) {
+  if (jacobian != nullptr) {
     tmp_jacobian.reset(
         down_cast<CompressedRowSparseMatrix*>(evaluator->CreateJacobian()));
   }
@@ -744,12 +739,13 @@
   Evaluator::EvaluateOptions evaluator_evaluate_options;
   evaluator_evaluate_options.apply_loss_function =
       evaluate_options.apply_loss_function;
-  bool status = evaluator->Evaluate(evaluator_evaluate_options,
-                                    parameters.data(),
-                                    &tmp_cost,
-                                    residuals != NULL ? &(*residuals)[0] : NULL,
-                                    gradient != NULL ? &(*gradient)[0] : NULL,
-                                    tmp_jacobian.get());
+  bool status =
+      evaluator->Evaluate(evaluator_evaluate_options,
+                          parameters.data(),
+                          &tmp_cost,
+                          residuals != nullptr ? &(*residuals)[0] : nullptr,
+                          gradient != nullptr ? &(*gradient)[0] : nullptr,
+                          tmp_jacobian.get());
 
   // Make the parameter blocks that were temporarily marked constant,
   // variable again.
@@ -758,10 +754,10 @@
   }
 
   if (status) {
-    if (cost != NULL) {
+    if (cost != nullptr) {
       *cost = tmp_cost;
     }
-    if (jacobian != NULL) {
+    if (jacobian != nullptr) {
       tmp_jacobian->ToCRSMatrix(jacobian);
     }
   }
@@ -771,26 +767,60 @@
   return status;
 }
 
+bool ProblemImpl::EvaluateResidualBlock(ResidualBlock* residual_block,
+                                        bool apply_loss_function,
+                                        bool new_point,
+                                        double* cost,
+                                        double* residuals,
+                                        double** jacobians) const {
+  auto evaluation_callback = program_->mutable_evaluation_callback();
+  if (evaluation_callback) {
+    evaluation_callback->PrepareForEvaluation(jacobians != nullptr, new_point);
+  }
+
+  ParameterBlock* const* parameter_blocks = residual_block->parameter_blocks();
+  const int num_parameter_blocks = residual_block->NumParameterBlocks();
+  for (int i = 0; i < num_parameter_blocks; ++i) {
+    ParameterBlock* parameter_block = parameter_blocks[i];
+    if (parameter_block->IsConstant()) {
+      if (jacobians != nullptr && jacobians[i] != nullptr) {
+        LOG(ERROR) << "Jacobian requested for parameter block : " << i
+                   << ". But the parameter block is marked constant.";
+        return false;
+      }
+    } else {
+      CHECK(parameter_block->SetState(parameter_block->user_state()))
+          << "Congratulations, you found a Ceres bug! Please report this error "
+          << "to the developers.";
+    }
+  }
+
+  double dummy_cost = 0.0;
+  FixedArray<double, 32> scratch(
+      residual_block->NumScratchDoublesForEvaluate());
+  return residual_block->Evaluate(apply_loss_function,
+                                  cost ? cost : &dummy_cost,
+                                  residuals,
+                                  jacobians,
+                                  scratch.data());
+}
+
 int ProblemImpl::NumParameterBlocks() const {
   return program_->NumParameterBlocks();
 }
 
-int ProblemImpl::NumParameters() const {
-  return program_->NumParameters();
-}
+int ProblemImpl::NumParameters() const { return program_->NumParameters(); }
 
 int ProblemImpl::NumResidualBlocks() const {
   return program_->NumResidualBlocks();
 }
 
-int ProblemImpl::NumResiduals() const {
-  return program_->NumResiduals();
-}
+int ProblemImpl::NumResiduals() const { return program_->NumResiduals(); }
 
 int ProblemImpl::ParameterBlockSize(const double* values) const {
-  ParameterBlock* parameter_block =
-      FindWithDefault(parameter_block_map_, const_cast<double*>(values), NULL);
-  if (parameter_block == NULL) {
+  ParameterBlock* parameter_block = FindWithDefault(
+      parameter_block_map_, const_cast<double*>(values), nullptr);
+  if (parameter_block == nullptr) {
     LOG(FATAL) << "Parameter block not found: " << values
                << ". You must add the parameter block to the problem before "
                << "you can get its size.";
@@ -800,9 +830,9 @@
 }
 
 int ProblemImpl::ParameterBlockLocalSize(const double* values) const {
-  ParameterBlock* parameter_block =
-      FindWithDefault(parameter_block_map_, const_cast<double*>(values), NULL);
-  if (parameter_block == NULL) {
+  ParameterBlock* parameter_block = FindWithDefault(
+      parameter_block_map_, const_cast<double*>(values), nullptr);
+  if (parameter_block == nullptr) {
     LOG(FATAL) << "Parameter block not found: " << values
                << ". You must add the parameter block to the problem before "
                << "you can get its local size.";
@@ -854,11 +884,10 @@
 }
 
 void ProblemImpl::GetResidualBlocksForParameterBlock(
-    const double* values,
-    vector<ResidualBlockId>* residual_blocks) const {
-  ParameterBlock* parameter_block =
-      FindWithDefault(parameter_block_map_, const_cast<double*>(values), NULL);
-  if (parameter_block == NULL) {
+    const double* values, vector<ResidualBlockId>* residual_blocks) const {
+  ParameterBlock* parameter_block = FindWithDefault(
+      parameter_block_map_, const_cast<double*>(values), nullptr);
+  if (parameter_block == nullptr) {
     LOG(FATAL) << "Parameter block not found: " << values
                << ". You must add the parameter block to the problem before "
                << "you can get the residual blocks that depend on it.";
@@ -880,8 +909,7 @@
   residual_blocks->clear();
   const int num_residual_blocks = NumResidualBlocks();
   for (int i = 0; i < num_residual_blocks; ++i) {
-    ResidualBlock* residual_block =
-        (*(program_->mutable_residual_blocks()))[i];
+    ResidualBlock* residual_block = (*(program_->mutable_residual_blocks()))[i];
     const int num_parameter_blocks = residual_block->NumParameterBlocks();
     for (int j = 0; j < num_parameter_blocks; ++j) {
       if (residual_block->parameter_blocks()[j] == parameter_block) {
diff --git a/internal/ceres/problem_impl.h b/internal/ceres/problem_impl.h
index eabeaed..9abff3f 100644
--- a/internal/ceres/problem_impl.h
+++ b/internal/ceres/problem_impl.h
@@ -1,5 +1,5 @@
 // Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2015 Google Inc. All rights reserved.
+// Copyright 2019 Google Inc. All rights reserved.
 // http://ceres-solver.org/
 //
 // Redistribution and use in source and binary forms, with or without
@@ -53,6 +53,7 @@
 namespace ceres {
 
 class CostFunction;
+class EvaluationCallback;
 class LossFunction;
 class LocalParameterization;
 struct CRSMatrix;
@@ -62,7 +63,7 @@
 class Program;
 class ResidualBlock;
 
-class ProblemImpl {
+class CERES_EXPORT_INTERNAL ProblemImpl {
  public:
   typedef std::map<double*, ParameterBlock*> ParameterMap;
   typedef std::unordered_set<ResidualBlock*> ResidualBlockSet;
@@ -77,11 +78,10 @@
   ~ProblemImpl();
 
   // See the public problem.h file for description of these methods.
-  ResidualBlockId AddResidualBlock(
-      CostFunction* cost_function,
-      LossFunction* loss_function,
-      double* const* const parameter_blocks,
-      int num_parameter_blocks);
+  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
+                                   LossFunction* loss_function,
+                                   double* const* const parameter_blocks,
+                                   int num_parameter_blocks);
 
   template <typename... Ts>
   ResidualBlockId AddResidualBlock(CostFunction* cost_function,
@@ -101,20 +101,20 @@
                          LocalParameterization* local_parameterization);
 
   void RemoveResidualBlock(ResidualBlock* residual_block);
-  void RemoveParameterBlock(double* values);
+  void RemoveParameterBlock(const double* values);
 
-  void SetParameterBlockConstant(double* values);
+  void SetParameterBlockConstant(const double* values);
   void SetParameterBlockVariable(double* values);
-  bool IsParameterBlockConstant(double* values) const;
+  bool IsParameterBlockConstant(const double* values) const;
 
   void SetParameterization(double* values,
                            LocalParameterization* local_parameterization);
-  const LocalParameterization* GetParameterization(double* values) const;
+  const LocalParameterization* GetParameterization(const double* values) const;
 
   void SetParameterLowerBound(double* values, int index, double lower_bound);
   void SetParameterUpperBound(double* values, int index, double upper_bound);
-  double GetParameterLowerBound(double* values, int index) const;
-  double GetParameterUpperBound(double* values, int index) const;
+  double GetParameterLowerBound(const double* values, int index) const;
+  double GetParameterUpperBound(const double* values, int index) const;
 
   bool Evaluate(const Problem::EvaluateOptions& options,
                 double* cost,
@@ -122,6 +122,13 @@
                 std::vector<double>* gradient,
                 CRSMatrix* jacobian);
 
+  bool EvaluateResidualBlock(ResidualBlock* residual_block,
+                             bool apply_loss_function,
+                             bool new_point,
+                             double* cost,
+                             double* residuals,
+                             double** jacobians) const;
+
   int NumParameterBlocks() const;
   int NumParameters() const;
   int NumResidualBlocks() const;
diff --git a/internal/ceres/problem_test.cc b/internal/ceres/problem_test.cc
index 3f9f804..5129b9a 100644
--- a/internal/ceres/problem_test.cc
+++ b/internal/ceres/problem_test.cc
@@ -30,9 +30,10 @@
 //         keir@google.com (Keir Mierle)
 
 #include "ceres/problem.h"
-#include "ceres/problem_impl.h"
 
 #include <memory>
+
+#include "ceres/autodiff_cost_function.h"
 #include "ceres/casts.h"
 #include "ceres/cost_function.h"
 #include "ceres/crs_matrix.h"
@@ -42,10 +43,12 @@
 #include "ceres/loss_function.h"
 #include "ceres/map_util.h"
 #include "ceres/parameter_block.h"
+#include "ceres/problem_impl.h"
 #include "ceres/program.h"
 #include "ceres/sized_cost_function.h"
 #include "ceres/sparse_matrix.h"
 #include "ceres/types.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -63,11 +66,12 @@
     set_num_residuals(num_residuals);
     mutable_parameter_block_sizes()->push_back(parameter_block_size);
   }
+
   virtual ~UnaryCostFunction() {}
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     for (int i = 0; i < num_residuals(); ++i) {
       residuals[i] = 1;
     }
@@ -76,7 +80,7 @@
 };
 
 // Trivial cost function that accepts two arguments.
-class BinaryCostFunction: public CostFunction {
+class BinaryCostFunction : public CostFunction {
  public:
   BinaryCostFunction(int num_residuals,
                      int32_t parameter_block1_size,
@@ -86,9 +90,9 @@
     mutable_parameter_block_sizes()->push_back(parameter_block2_size);
   }
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     for (int i = 0; i < num_residuals(); ++i) {
       residuals[i] = 2;
     }
@@ -97,7 +101,7 @@
 };
 
 // Trivial cost function that accepts three arguments.
-class TernaryCostFunction: public CostFunction {
+class TernaryCostFunction : public CostFunction {
  public:
   TernaryCostFunction(int num_residuals,
                       int32_t parameter_block1_size,
@@ -109,9 +113,9 @@
     mutable_parameter_block_sizes()->push_back(parameter_block3_size);
   }
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     for (int i = 0; i < num_residuals(); ++i) {
       residuals[i] = 3;
     }
@@ -119,6 +123,23 @@
   }
 };
 
+TEST(Problem, MoveConstructor) {
+  Problem src;
+  double x;
+  src.AddParameterBlock(&x, 1);
+  Problem dst(std::move(src));
+  EXPECT_TRUE(dst.HasParameterBlock(&x));
+}
+
+TEST(Problem, MoveAssignment) {
+  Problem src;
+  double x;
+  src.AddParameterBlock(&x, 1);
+  Problem dst;
+  dst = std::move(src);
+  EXPECT_TRUE(dst.HasParameterBlock(&x));
+}
+
 TEST(Problem, AddResidualWithNullCostFunctionDies) {
   double x[3], y[4], z[5];
 
@@ -150,23 +171,23 @@
 
   Problem problem;
   problem.AddResidualBlock(new UnaryCostFunction(2, 3), NULL, x);
-  EXPECT_DEATH_IF_SUPPORTED(problem.AddResidualBlock(
-                                new UnaryCostFunction(
-                                    2, 4 /* 4 != 3 */), NULL, x),
-                            "different block sizes");
+  EXPECT_DEATH_IF_SUPPORTED(
+      problem.AddResidualBlock(
+          new UnaryCostFunction(2, 4 /* 4 != 3 */), NULL, x),
+      "different block sizes");
 }
 
 TEST(Problem, AddResidualWithDuplicateParametersDies) {
   double x[3], z[5];
 
   Problem problem;
-  EXPECT_DEATH_IF_SUPPORTED(problem.AddResidualBlock(
-                                new BinaryCostFunction(2, 3, 3), NULL, x, x),
-                            "Duplicate parameter blocks");
-  EXPECT_DEATH_IF_SUPPORTED(problem.AddResidualBlock(
-                                new TernaryCostFunction(1, 5, 3, 5),
-                                NULL, z, x, z),
-                            "Duplicate parameter blocks");
+  EXPECT_DEATH_IF_SUPPORTED(
+      problem.AddResidualBlock(new BinaryCostFunction(2, 3, 3), NULL, x, x),
+      "Duplicate parameter blocks");
+  EXPECT_DEATH_IF_SUPPORTED(
+      problem.AddResidualBlock(
+          new TernaryCostFunction(1, 5, 3, 5), NULL, z, x, z),
+      "Duplicate parameter blocks");
 }
 
 TEST(Problem, AddResidualWithIncorrectSizesOfParameterBlockDies) {
@@ -179,9 +200,9 @@
 
   // The cost function expects the size of the second parameter, z, to be 4
   // instead of 5 as declared above. This is fatal.
-  EXPECT_DEATH_IF_SUPPORTED(problem.AddResidualBlock(
-      new BinaryCostFunction(2, 3, 4), NULL, x, z),
-               "different block sizes");
+  EXPECT_DEATH_IF_SUPPORTED(
+      problem.AddResidualBlock(new BinaryCostFunction(2, 3, 4), NULL, x, z),
+      "different block sizes");
 }
 
 TEST(Problem, AddResidualAddsDuplicatedParametersOnlyOnce) {
@@ -208,7 +229,7 @@
                             "different block sizes");
 }
 
-static double *IntToPtr(int i) {
+static double* IntToPtr(int i) {
   return reinterpret_cast<double*>(sizeof(double) * i);  // NOLINT
 }
 
@@ -224,16 +245,16 @@
   // ones marked with o==o and aliasing ones marked with o--o.
 
   Problem problem;
-  problem.AddParameterBlock(IntToPtr(5),  5);  // x
+  problem.AddParameterBlock(IntToPtr(5), 5);   // x
   problem.AddParameterBlock(IntToPtr(13), 3);  // y
 
-  EXPECT_DEATH_IF_SUPPORTED(problem.AddParameterBlock(IntToPtr( 4), 2),
+  EXPECT_DEATH_IF_SUPPORTED(problem.AddParameterBlock(IntToPtr(4), 2),
                             "Aliasing detected");
-  EXPECT_DEATH_IF_SUPPORTED(problem.AddParameterBlock(IntToPtr( 4), 3),
+  EXPECT_DEATH_IF_SUPPORTED(problem.AddParameterBlock(IntToPtr(4), 3),
                             "Aliasing detected");
-  EXPECT_DEATH_IF_SUPPORTED(problem.AddParameterBlock(IntToPtr( 4), 9),
+  EXPECT_DEATH_IF_SUPPORTED(problem.AddParameterBlock(IntToPtr(4), 9),
                             "Aliasing detected");
-  EXPECT_DEATH_IF_SUPPORTED(problem.AddParameterBlock(IntToPtr( 8), 3),
+  EXPECT_DEATH_IF_SUPPORTED(problem.AddParameterBlock(IntToPtr(8), 3),
                             "Aliasing detected");
   EXPECT_DEATH_IF_SUPPORTED(problem.AddParameterBlock(IntToPtr(12), 2),
                             "Aliasing detected");
@@ -241,7 +262,7 @@
                             "Aliasing detected");
 
   // These ones should work.
-  problem.AddParameterBlock(IntToPtr( 2), 3);
+  problem.AddParameterBlock(IntToPtr(2), 3);
   problem.AddParameterBlock(IntToPtr(10), 3);
   problem.AddParameterBlock(IntToPtr(16), 2);
 
@@ -284,17 +305,20 @@
   EXPECT_EQ(7, problem.NumParameters());
 
   problem.AddParameterBlock(z, 5);
-  EXPECT_EQ(3,  problem.NumParameterBlocks());
+  EXPECT_EQ(3, problem.NumParameterBlocks());
   EXPECT_EQ(12, problem.NumParameters());
 
   // Add a parameter that has a local parameterization.
-  w[0] = 1.0; w[1] = 0.0; w[2] = 0.0; w[3] = 0.0;
+  w[0] = 1.0;
+  w[1] = 0.0;
+  w[2] = 0.0;
+  w[3] = 0.0;
   problem.AddParameterBlock(w, 4, new QuaternionParameterization);
-  EXPECT_EQ(4,  problem.NumParameterBlocks());
+  EXPECT_EQ(4, problem.NumParameterBlocks());
   EXPECT_EQ(16, problem.NumParameters());
 
   problem.AddResidualBlock(new UnaryCostFunction(2, 3), NULL, x);
-  problem.AddResidualBlock(new BinaryCostFunction(6, 5, 4) , NULL, z, y);
+  problem.AddResidualBlock(new BinaryCostFunction(6, 5, 4), NULL, z, y);
   problem.AddResidualBlock(new BinaryCostFunction(3, 3, 5), NULL, x, z);
   problem.AddResidualBlock(new BinaryCostFunction(7, 5, 3), NULL, z, x);
   problem.AddResidualBlock(new TernaryCostFunction(1, 5, 3, 4), NULL, z, x, y);
@@ -306,16 +330,14 @@
 
 class DestructorCountingCostFunction : public SizedCostFunction<3, 4, 5> {
  public:
-  explicit DestructorCountingCostFunction(int *num_destructions)
+  explicit DestructorCountingCostFunction(int* num_destructions)
       : num_destructions_(num_destructions) {}
 
-  virtual ~DestructorCountingCostFunction() {
-    *num_destructions_ += 1;
-  }
+  virtual ~DestructorCountingCostFunction() { *num_destructions_ += 1; }
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     return true;
   }
 
@@ -441,8 +463,7 @@
   // The next block of functions until the end are only for testing the
   // residual block removals.
   void ExpectParameterBlockContainsResidualBlock(
-      double* values,
-      ResidualBlock* residual_block) {
+      double* values, ResidualBlock* residual_block) {
     ParameterBlock* parameter_block =
         FindOrDie(problem->parameter_map(), values);
     EXPECT_TRUE(ContainsKey(*(parameter_block->mutable_residual_blocks()),
@@ -456,12 +477,9 @@
   }
 
   // Degenerate case.
-  void ExpectParameterBlockContains(double* values) {
-    ExpectSize(values, 0);
-  }
+  void ExpectParameterBlockContains(double* values) { ExpectSize(values, 0); }
 
-  void ExpectParameterBlockContains(double* values,
-                                    ResidualBlock* r1) {
+  void ExpectParameterBlockContains(double* values, ResidualBlock* r1) {
     ExpectSize(values, 1);
     ExpectParameterBlockContainsResidualBlock(values, r1);
   }
@@ -576,8 +594,8 @@
   Problem problem;
   problem.AddParameterBlock(x, 3);
 
-  EXPECT_DEATH_IF_SUPPORTED(
-      problem.RemoveParameterBlock(y), "Parameter block not found:");
+  EXPECT_DEATH_IF_SUPPORTED(problem.RemoveParameterBlock(y),
+                            "Parameter block not found:");
 }
 
 TEST(Problem, GetParameterization) {
@@ -588,7 +606,7 @@
   problem.AddParameterBlock(x, 3);
   problem.AddParameterBlock(y, 2);
 
-  LocalParameterization* parameterization =  new IdentityParameterization(3);
+  LocalParameterization* parameterization = new IdentityParameterization(3);
   problem.SetParameterization(x, parameterization);
   EXPECT_EQ(problem.GetParameterization(x), parameterization);
   EXPECT_TRUE(problem.GetParameterization(y) == NULL);
@@ -604,8 +622,7 @@
   vector<int> constant_parameters;
   constant_parameters.push_back(0);
   problem.SetParameterization(
-      x,
-      new SubsetParameterization(3, constant_parameters));
+      x, new SubsetParameterization(3, constant_parameters));
   EXPECT_EQ(problem.ParameterBlockSize(x), 3);
   EXPECT_EQ(problem.ParameterBlockLocalSize(x), 2);
   EXPECT_EQ(problem.ParameterBlockLocalSize(y), 4);
@@ -692,6 +709,8 @@
   EXPECT_EQ(z, GetParameterBlock(1)->user_state());
   EXPECT_EQ(w, GetParameterBlock(2)->user_state());
 
+  // clang-format off
+
   // Add all combinations of cost functions.
   CostFunction* cost_yzw = new TernaryCostFunction(1, 4, 5, 3);
   CostFunction* cost_yz  = new BinaryCostFunction (1, 4, 5);
@@ -742,6 +761,8 @@
   problem->RemoveParameterBlock(y);
   EXPECT_EQ(0, problem->NumParameterBlocks());
   EXPECT_EQ(0, NumResidualBlocks());
+
+  // clang-format on
 }
 
 TEST_P(DynamicProblem, RemoveResidualBlock) {
@@ -749,6 +770,8 @@
   problem->AddParameterBlock(z, 5);
   problem->AddParameterBlock(w, 3);
 
+  // clang-format off
+
   // Add all combinations of cost functions.
   CostFunction* cost_yzw = new TernaryCostFunction(1, 4, 5, 3);
   CostFunction* cost_yz  = new BinaryCostFunction (1, 4, 5);
@@ -863,6 +886,8 @@
     ExpectParameterBlockContains(z);
     ExpectParameterBlockContains(w);
   }
+
+  // clang-format on
 }
 
 TEST_P(DynamicProblem, RemoveInvalidResidualBlockDies) {
@@ -870,6 +895,8 @@
   problem->AddParameterBlock(z, 5);
   problem->AddParameterBlock(w, 3);
 
+  // clang-format off
+
   // Add all combinations of cost functions.
   CostFunction* cost_yzw = new TernaryCostFunction(1, 4, 5, 3);
   CostFunction* cost_yz  = new BinaryCostFunction (1, 4, 5);
@@ -887,6 +914,8 @@
   ResidualBlock* r_z   = problem->AddResidualBlock(cost_z,   NULL, z);
   ResidualBlock* r_w   = problem->AddResidualBlock(cost_w,   NULL, w);
 
+  // clang-format on
+
   // Remove r_yzw.
   problem->RemoveResidualBlock(r_yzw);
   ASSERT_EQ(3, problem->NumParameterBlocks());
@@ -916,7 +945,7 @@
 }
 
 // Check that a null-terminated array, a, has the same elements as b.
-template<typename T>
+template <typename T>
 void ExpectVectorContainsUnordered(const T* a, const vector<T>& b) {
   // Compute the size of a.
   int size = 0;
@@ -940,9 +969,9 @@
   }
 }
 
-void ExpectProblemHasResidualBlocks(
-    const ProblemImpl &problem,
-    const ResidualBlockId *expected_residual_blocks) {
+static void ExpectProblemHasResidualBlocks(
+    const ProblemImpl& problem,
+    const ResidualBlockId* expected_residual_blocks) {
   vector<ResidualBlockId> residual_blocks;
   problem.GetResidualBlocks(&residual_blocks);
   ExpectVectorContainsUnordered(expected_residual_blocks, residual_blocks);
@@ -953,6 +982,8 @@
   problem->AddParameterBlock(z, 5);
   problem->AddParameterBlock(w, 3);
 
+  // clang-format off
+
   // Add all combinations of cost functions.
   CostFunction* cost_yzw = new TernaryCostFunction(1, 4, 5, 3);
   CostFunction* cost_yz  = new BinaryCostFunction (1, 4, 5);
@@ -1048,11 +1079,13 @@
         get_parameter_blocks_cases[i].expected_parameter_blocks,
         parameter_blocks);
   }
+
+  // clang-format on
 }
 
-INSTANTIATE_TEST_CASE_P(OptionsInstantiation,
-                        DynamicProblem,
-                        ::testing::Values(true, false));
+INSTANTIATE_TEST_SUITE_P(OptionsInstantiation,
+                         DynamicProblem,
+                         ::testing::Values(true, false));
 
 // Test for Problem::Evaluate
 
@@ -1069,9 +1102,9 @@
     }
   }
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     for (int i = 0; i < kNumResiduals; ++i) {
       residuals[i] = i;
       for (int j = 0; j < kNumParameterBlocks; ++j) {
@@ -1086,8 +1119,8 @@
     for (int j = 0; j < kNumParameterBlocks; ++j) {
       if (jacobians[j] != NULL) {
         MatrixRef(jacobians[j], kNumResiduals, kNumResiduals) =
-            (-2.0 * (j + 1.0) *
-             ConstVectorRef(parameters[j], kNumResiduals)).asDiagonal();
+            (-2.0 * (j + 1.0) * ConstVectorRef(parameters[j], kNumResiduals))
+                .asDiagonal();
       }
     }
 
@@ -1096,7 +1129,7 @@
 };
 
 // Convert a CRSMatrix to a dense Eigen matrix.
-void CRSToDenseMatrix(const CRSMatrix& input, Matrix* output) {
+static void CRSToDenseMatrix(const CRSMatrix& input, Matrix* output) {
   CHECK(output != nullptr);
   Matrix& m = *output;
   m.resize(input.num_rows, input.num_cols);
@@ -1120,31 +1153,20 @@
     parameter_blocks_.push_back(parameters_ + 2);
     parameter_blocks_.push_back(parameters_ + 4);
 
-
     CostFunction* cost_function = new QuadraticCostFunction<2, 2>;
 
     // f(x, y)
-    residual_blocks_.push_back(
-        problem_.AddResidualBlock(cost_function,
-                                  NULL,
-                                  parameters_,
-                                  parameters_ + 2));
+    residual_blocks_.push_back(problem_.AddResidualBlock(
+        cost_function, NULL, parameters_, parameters_ + 2));
     // g(y, z)
-    residual_blocks_.push_back(
-        problem_.AddResidualBlock(cost_function,
-                                  NULL, parameters_ + 2,
-                                  parameters_ + 4));
+    residual_blocks_.push_back(problem_.AddResidualBlock(
+        cost_function, NULL, parameters_ + 2, parameters_ + 4));
     // h(z, x)
-    residual_blocks_.push_back(
-        problem_.AddResidualBlock(cost_function,
-                                  NULL,
-                                  parameters_ + 4,
-                                  parameters_));
+    residual_blocks_.push_back(problem_.AddResidualBlock(
+        cost_function, NULL, parameters_ + 4, parameters_));
   }
 
-  void TearDown() {
-    EXPECT_TRUE(problem_.program().IsValid());
-  }
+  void TearDown() { EXPECT_TRUE(problem_.program().IsValid()); }
 
   void EvaluateAndCompare(const Problem::EvaluateOptions& options,
                           const int expected_num_rows,
@@ -1203,8 +1225,8 @@
                          expected.num_cols,
                          expected.cost,
                          (i & 1) ? expected.residuals : NULL,
-                         (i & 2) ? expected.gradient  : NULL,
-                         (i & 4) ? expected.jacobian  : NULL);
+                         (i & 2) ? expected.gradient : NULL,
+                         (i & 4) ? expected.jacobian : NULL);
     }
   }
 
@@ -1214,8 +1236,8 @@
   vector<ResidualBlockId> residual_blocks_;
 };
 
-
 TEST_F(ProblemEvaluateTest, MultipleParameterAndResidualBlocks) {
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     6, 6,
@@ -1241,11 +1263,13 @@
                      0.0, -8.0,   0.0,   0.0,   0.0, -12.0
     }
   };
+  // clang-format on
 
   CheckAllEvaluationCombinations(Problem::EvaluateOptions(), expected);
 }
 
 TEST_F(ProblemEvaluateTest, ParameterAndResidualBlocksPassedInOptions) {
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     6, 6,
@@ -1271,6 +1295,7 @@
                      0.0, -8.0,   0.0,   0.0,   0.0, -12.0
     }
   };
+  // clang-format on
 
   Problem::EvaluateOptions evaluate_options;
   evaluate_options.parameter_blocks = parameter_blocks_;
@@ -1279,6 +1304,7 @@
 }
 
 TEST_F(ProblemEvaluateTest, ReorderedResidualBlocks) {
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     6, 6,
@@ -1304,6 +1330,7 @@
                      0.0,  0.0,   0.0,  -8.0,   0.0, -24.0
     }
   };
+  // clang-format on
 
   Problem::EvaluateOptions evaluate_options;
   evaluate_options.parameter_blocks = parameter_blocks_;
@@ -1316,7 +1343,9 @@
   CheckAllEvaluationCombinations(evaluate_options, expected);
 }
 
-TEST_F(ProblemEvaluateTest, ReorderedResidualBlocksAndReorderedParameterBlocks) {
+TEST_F(ProblemEvaluateTest,
+       ReorderedResidualBlocksAndReorderedParameterBlocks) {
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     6, 6,
@@ -1342,6 +1371,7 @@
                       0.0, -24.0,   0.0,  -8.0,   0.0,   0.0
     }
   };
+  // clang-format on
 
   Problem::EvaluateOptions evaluate_options;
   // z, y, x
@@ -1358,6 +1388,7 @@
 }
 
 TEST_F(ProblemEvaluateTest, ConstantParameterBlock) {
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     6, 6,
@@ -1385,12 +1416,14 @@
                      0.0, -8.0,   0.0,   0.0,   0.0, -12.0
     }
   };
+  // clang-format on
 
   problem_.SetParameterBlockConstant(parameters_ + 2);
   CheckAllEvaluationCombinations(Problem::EvaluateOptions(), expected);
 }
 
 TEST_F(ProblemEvaluateTest, ExcludedAResidualBlock) {
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     4, 6,
@@ -1413,6 +1446,7 @@
                      0.0, -8.0,   0.0,   0.0,   0.0, -12.0
     }
   };
+  // clang-format on
 
   Problem::EvaluateOptions evaluate_options;
   evaluate_options.residual_blocks.push_back(residual_blocks_[0]);
@@ -1422,6 +1456,7 @@
 }
 
 TEST_F(ProblemEvaluateTest, ExcludedParameterBlock) {
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     6, 4,
@@ -1448,6 +1483,7 @@
                      0.0, -8.0,   0.0, -12.0
     }
   };
+  // clang-format on
 
   Problem::EvaluateOptions evaluate_options;
   // x, z
@@ -1458,6 +1494,7 @@
 }
 
 TEST_F(ProblemEvaluateTest, ExcludedParameterBlockAndExcludedResidualBlock) {
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     4, 4,
@@ -1481,6 +1518,7 @@
                      0.0,  0.0,   0.0, -24.0,
     }
   };
+  // clang-format on
 
   Problem::EvaluateOptions evaluate_options;
   // x, z
@@ -1493,6 +1531,7 @@
 }
 
 TEST_F(ProblemEvaluateTest, LocalParameterization) {
+  // clang-format off
   ExpectedEvaluation expected = {
     // Rows/columns
     6, 5,
@@ -1518,16 +1557,534 @@
                      0.0, -8.0,   0.0,   0.0, -12.0
     }
   };
+  // clang-format on
 
   vector<int> constant_parameters;
   constant_parameters.push_back(0);
-  problem_.SetParameterization(parameters_ + 2,
-                               new SubsetParameterization(2,
-                                                          constant_parameters));
+  problem_.SetParameterization(
+      parameters_ + 2, new SubsetParameterization(2, constant_parameters));
 
   CheckAllEvaluationCombinations(Problem::EvaluateOptions(), expected);
 }
 
+struct IdentityFunctor {
+  template <typename T>
+  bool operator()(const T* x, const T* y, T* residuals) const {
+    residuals[0] = x[0];
+    residuals[1] = x[1];
+    residuals[2] = y[0];
+    residuals[3] = y[1];
+    residuals[4] = y[2];
+    return true;
+  }
+
+  static CostFunction* Create() {
+    return new AutoDiffCostFunction<IdentityFunctor, 5, 2, 3>(
+        new IdentityFunctor);
+  }
+};
+
+class ProblemEvaluateResidualBlockTest : public ::testing::Test {
+ public:
+  static constexpr bool kApplyLossFunction = true;
+  static constexpr bool kDoNotApplyLossFunction = false;
+  static constexpr bool kNewPoint = true;
+  static constexpr bool kNotNewPoint = false;
+  static double loss_function_scale_;
+
+ protected:
+  ProblemImpl problem_;
+  double x_[2] = {1, 2};
+  double y_[3] = {1, 2, 3};
+};
+
+double ProblemEvaluateResidualBlockTest::loss_function_scale_ = 2.0;
+
+TEST_F(ProblemEvaluateResidualBlockTest,
+       OneResidualBlockNoLossFunctionFullEval) {
+  ResidualBlockId residual_block_id =
+      problem_.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+  Vector expected_f(5);
+  expected_f << 1, 2, 1, 2, 3;
+  Matrix expected_dfdx = Matrix::Zero(5, 2);
+  expected_dfdx.block(0, 0, 2, 2) = Matrix::Identity(2, 2);
+  Matrix expected_dfdy = Matrix::Zero(5, 3);
+  expected_dfdy.block(2, 0, 3, 3) = Matrix::Identity(3, 3);
+  double expected_cost = expected_f.squaredNorm() / 2.0;
+
+  double actual_cost;
+  Vector actual_f(5);
+  Matrix actual_dfdx(5, 2);
+  Matrix actual_dfdy(5, 3);
+  double* jacobians[2] = {actual_dfdx.data(), actual_dfdy.data()};
+  EXPECT_TRUE(problem_.EvaluateResidualBlock(residual_block_id,
+                                             kApplyLossFunction,
+                                             kNewPoint,
+                                             &actual_cost,
+                                             actual_f.data(),
+                                             jacobians));
+
+  EXPECT_NEAR(std::abs(expected_cost - actual_cost) / actual_cost,
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_cost;
+  EXPECT_NEAR((expected_f - actual_f).norm() / actual_f.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_f;
+  EXPECT_NEAR((expected_dfdx - actual_dfdx).norm() / actual_dfdx.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_dfdx;
+  EXPECT_NEAR((expected_dfdy - actual_dfdy).norm() / actual_dfdy.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_dfdy;
+}
+
+TEST_F(ProblemEvaluateResidualBlockTest,
+       OneResidualBlockNoLossFunctionNullEval) {
+  ResidualBlockId residual_block_id =
+      problem_.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+  EXPECT_TRUE(problem_.EvaluateResidualBlock(residual_block_id,
+                                             kApplyLossFunction,
+                                             kNewPoint,
+                                             nullptr,
+                                             nullptr,
+                                             nullptr));
+}
+
+TEST_F(ProblemEvaluateResidualBlockTest, OneResidualBlockNoLossFunctionCost) {
+  ResidualBlockId residual_block_id =
+      problem_.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+  Vector expected_f(5);
+  expected_f << 1, 2, 1, 2, 3;
+  double expected_cost = expected_f.squaredNorm() / 2.0;
+
+  double actual_cost;
+  EXPECT_TRUE(problem_.EvaluateResidualBlock(residual_block_id,
+                                             kApplyLossFunction,
+                                             kNewPoint,
+                                             &actual_cost,
+                                             nullptr,
+                                             nullptr));
+
+  EXPECT_NEAR(std::abs(expected_cost - actual_cost) / actual_cost,
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_cost;
+}
+
+TEST_F(ProblemEvaluateResidualBlockTest,
+       OneResidualBlockNoLossFunctionCostAndResidual) {
+  ResidualBlockId residual_block_id =
+      problem_.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+  Vector expected_f(5);
+  expected_f << 1, 2, 1, 2, 3;
+  double expected_cost = expected_f.squaredNorm() / 2.0;
+
+  double actual_cost;
+  Vector actual_f(5);
+  EXPECT_TRUE(problem_.EvaluateResidualBlock(residual_block_id,
+                                             kApplyLossFunction,
+                                             kNewPoint,
+                                             &actual_cost,
+                                             actual_f.data(),
+                                             nullptr));
+
+  EXPECT_NEAR(std::abs(expected_cost - actual_cost) / actual_cost,
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_cost;
+  EXPECT_NEAR((expected_f - actual_f).norm() / actual_f.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_f;
+}
+
+TEST_F(ProblemEvaluateResidualBlockTest,
+       OneResidualBlockNoLossFunctionCostResidualAndOneJacobian) {
+  ResidualBlockId residual_block_id =
+      problem_.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+  Vector expected_f(5);
+  expected_f << 1, 2, 1, 2, 3;
+  Matrix expected_dfdx = Matrix::Zero(5, 2);
+  expected_dfdx.block(0, 0, 2, 2) = Matrix::Identity(2, 2);
+  double expected_cost = expected_f.squaredNorm() / 2.0;
+
+  double actual_cost;
+  Vector actual_f(5);
+  Matrix actual_dfdx(5, 2);
+  double* jacobians[2] = {actual_dfdx.data(), nullptr};
+  EXPECT_TRUE(problem_.EvaluateResidualBlock(residual_block_id,
+                                             kApplyLossFunction,
+                                             kNewPoint,
+                                             &actual_cost,
+                                             actual_f.data(),
+                                             jacobians));
+
+  EXPECT_NEAR(std::abs(expected_cost - actual_cost) / actual_cost,
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_cost;
+  EXPECT_NEAR((expected_f - actual_f).norm() / actual_f.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_f;
+  EXPECT_NEAR((expected_dfdx - actual_dfdx).norm() / actual_dfdx.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_dfdx;
+}
+
+TEST_F(ProblemEvaluateResidualBlockTest,
+       OneResidualBlockNoLossFunctionResidual) {
+  ResidualBlockId residual_block_id =
+      problem_.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+  Vector expected_f(5);
+  expected_f << 1, 2, 1, 2, 3;
+  Vector actual_f(5);
+  EXPECT_TRUE(problem_.EvaluateResidualBlock(residual_block_id,
+                                             kApplyLossFunction,
+                                             kNewPoint,
+                                             nullptr,
+                                             actual_f.data(),
+                                             nullptr));
+
+  EXPECT_NEAR((expected_f - actual_f).norm() / actual_f.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_f;
+}
+
+TEST_F(ProblemEvaluateResidualBlockTest, OneResidualBlockWithLossFunction) {
+  ResidualBlockId residual_block_id =
+      problem_.AddResidualBlock(IdentityFunctor::Create(),
+                                new ScaledLoss(nullptr, 2.0, TAKE_OWNERSHIP),
+                                x_,
+                                y_);
+  Vector expected_f(5);
+  expected_f << 1, 2, 1, 2, 3;
+  expected_f *= std::sqrt(loss_function_scale_);
+  Matrix expected_dfdx = Matrix::Zero(5, 2);
+  expected_dfdx.block(0, 0, 2, 2) = Matrix::Identity(2, 2);
+  expected_dfdx *= std::sqrt(loss_function_scale_);
+  Matrix expected_dfdy = Matrix::Zero(5, 3);
+  expected_dfdy.block(2, 0, 3, 3) = Matrix::Identity(3, 3);
+  expected_dfdy *= std::sqrt(loss_function_scale_);
+  double expected_cost = expected_f.squaredNorm() / 2.0;
+
+  double actual_cost;
+  Vector actual_f(5);
+  Matrix actual_dfdx(5, 2);
+  Matrix actual_dfdy(5, 3);
+  double* jacobians[2] = {actual_dfdx.data(), actual_dfdy.data()};
+  EXPECT_TRUE(problem_.EvaluateResidualBlock(residual_block_id,
+                                             kApplyLossFunction,
+                                             kNewPoint,
+                                             &actual_cost,
+                                             actual_f.data(),
+                                             jacobians));
+
+  EXPECT_NEAR(std::abs(expected_cost - actual_cost) / actual_cost,
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_cost;
+  EXPECT_NEAR((expected_f - actual_f).norm() / actual_f.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_f;
+  EXPECT_NEAR((expected_dfdx - actual_dfdx).norm() / actual_dfdx.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_dfdx;
+  EXPECT_NEAR((expected_dfdy - actual_dfdy).norm() / actual_dfdy.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_dfdy;
+}
+
+TEST_F(ProblemEvaluateResidualBlockTest,
+       OneResidualBlockWithLossFunctionDisabled) {
+  ResidualBlockId residual_block_id =
+      problem_.AddResidualBlock(IdentityFunctor::Create(),
+                                new ScaledLoss(nullptr, 2.0, TAKE_OWNERSHIP),
+                                x_,
+                                y_);
+  Vector expected_f(5);
+  expected_f << 1, 2, 1, 2, 3;
+  Matrix expected_dfdx = Matrix::Zero(5, 2);
+  expected_dfdx.block(0, 0, 2, 2) = Matrix::Identity(2, 2);
+  Matrix expected_dfdy = Matrix::Zero(5, 3);
+  expected_dfdy.block(2, 0, 3, 3) = Matrix::Identity(3, 3);
+  double expected_cost = expected_f.squaredNorm() / 2.0;
+
+  double actual_cost;
+  Vector actual_f(5);
+  Matrix actual_dfdx(5, 2);
+  Matrix actual_dfdy(5, 3);
+  double* jacobians[2] = {actual_dfdx.data(), actual_dfdy.data()};
+  EXPECT_TRUE(problem_.EvaluateResidualBlock(residual_block_id,
+                                             kDoNotApplyLossFunction,
+                                             kNewPoint,
+                                             &actual_cost,
+                                             actual_f.data(),
+                                             jacobians));
+
+  EXPECT_NEAR(std::abs(expected_cost - actual_cost) / actual_cost,
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_cost;
+  EXPECT_NEAR((expected_f - actual_f).norm() / actual_f.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_f;
+  EXPECT_NEAR((expected_dfdx - actual_dfdx).norm() / actual_dfdx.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_dfdx;
+  EXPECT_NEAR((expected_dfdy - actual_dfdy).norm() / actual_dfdy.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_dfdy;
+}
+
+TEST_F(ProblemEvaluateResidualBlockTest,
+       OneResidualBlockWithOneLocalParameterization) {
+  ResidualBlockId residual_block_id =
+      problem_.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+  problem_.SetParameterization(x_, new SubsetParameterization(2, {1}));
+
+  Vector expected_f(5);
+  expected_f << 1, 2, 1, 2, 3;
+  Matrix expected_dfdx = Matrix::Zero(5, 1);
+  expected_dfdx.block(0, 0, 1, 1) = Matrix::Identity(1, 1);
+  Matrix expected_dfdy = Matrix::Zero(5, 3);
+  expected_dfdy.block(2, 0, 3, 3) = Matrix::Identity(3, 3);
+  double expected_cost = expected_f.squaredNorm() / 2.0;
+
+  double actual_cost;
+  Vector actual_f(5);
+  Matrix actual_dfdx(5, 1);
+  Matrix actual_dfdy(5, 3);
+  double* jacobians[2] = {actual_dfdx.data(), actual_dfdy.data()};
+  EXPECT_TRUE(problem_.EvaluateResidualBlock(residual_block_id,
+                                             kApplyLossFunction,
+                                             kNewPoint,
+                                             &actual_cost,
+                                             actual_f.data(),
+                                             jacobians));
+
+  EXPECT_NEAR(std::abs(expected_cost - actual_cost) / actual_cost,
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_cost;
+  EXPECT_NEAR((expected_f - actual_f).norm() / actual_f.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_f;
+  EXPECT_NEAR((expected_dfdx - actual_dfdx).norm() / actual_dfdx.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_dfdx;
+  EXPECT_NEAR((expected_dfdy - actual_dfdy).norm() / actual_dfdy.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_dfdy;
+}
+
+TEST_F(ProblemEvaluateResidualBlockTest,
+       OneResidualBlockWithTwoLocalParameterizations) {
+  ResidualBlockId residual_block_id =
+      problem_.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+  problem_.SetParameterization(x_, new SubsetParameterization(2, {1}));
+  problem_.SetParameterization(y_, new SubsetParameterization(3, {2}));
+
+  Vector expected_f(5);
+  expected_f << 1, 2, 1, 2, 3;
+  Matrix expected_dfdx = Matrix::Zero(5, 1);
+  expected_dfdx.block(0, 0, 1, 1) = Matrix::Identity(1, 1);
+  Matrix expected_dfdy = Matrix::Zero(5, 2);
+  expected_dfdy.block(2, 0, 2, 2) = Matrix::Identity(2, 2);
+  double expected_cost = expected_f.squaredNorm() / 2.0;
+
+  double actual_cost;
+  Vector actual_f(5);
+  Matrix actual_dfdx(5, 1);
+  Matrix actual_dfdy(5, 2);
+  double* jacobians[2] = {actual_dfdx.data(), actual_dfdy.data()};
+  EXPECT_TRUE(problem_.EvaluateResidualBlock(residual_block_id,
+                                             kApplyLossFunction,
+                                             kNewPoint,
+                                             &actual_cost,
+                                             actual_f.data(),
+                                             jacobians));
+
+  EXPECT_NEAR(std::abs(expected_cost - actual_cost) / actual_cost,
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_cost;
+  EXPECT_NEAR((expected_f - actual_f).norm() / actual_f.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_f;
+  EXPECT_NEAR((expected_dfdx - actual_dfdx).norm() / actual_dfdx.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_dfdx;
+  EXPECT_NEAR((expected_dfdy - actual_dfdy).norm() / actual_dfdy.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_dfdy;
+}
+
+TEST_F(ProblemEvaluateResidualBlockTest,
+       OneResidualBlockWithOneConstantParameterBlock) {
+  ResidualBlockId residual_block_id =
+      problem_.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+  problem_.SetParameterBlockConstant(x_);
+
+  Vector expected_f(5);
+  expected_f << 1, 2, 1, 2, 3;
+  Matrix expected_dfdy = Matrix::Zero(5, 3);
+  expected_dfdy.block(2, 0, 3, 3) = Matrix::Identity(3, 3);
+  double expected_cost = expected_f.squaredNorm() / 2.0;
+
+  double actual_cost;
+  Vector actual_f(5);
+  Matrix actual_dfdx(5, 2);
+  Matrix actual_dfdy(5, 3);
+
+  // Try evaluating both Jacobians, this should fail.
+  double* jacobians[2] = {actual_dfdx.data(), actual_dfdy.data()};
+  EXPECT_FALSE(problem_.EvaluateResidualBlock(residual_block_id,
+                                              kApplyLossFunction,
+                                              kNewPoint,
+                                              &actual_cost,
+                                              actual_f.data(),
+                                              jacobians));
+
+  jacobians[0] = nullptr;
+  EXPECT_TRUE(problem_.EvaluateResidualBlock(residual_block_id,
+                                             kApplyLossFunction,
+                                             kNewPoint,
+                                             &actual_cost,
+                                             actual_f.data(),
+                                             jacobians));
+
+  EXPECT_NEAR(std::abs(expected_cost - actual_cost) / actual_cost,
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_cost;
+  EXPECT_NEAR((expected_f - actual_f).norm() / actual_f.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_f;
+  EXPECT_NEAR((expected_dfdy - actual_dfdy).norm() / actual_dfdy.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_dfdy;
+}
+
+TEST_F(ProblemEvaluateResidualBlockTest,
+       OneResidualBlockWithAllConstantParameterBlocks) {
+  ResidualBlockId residual_block_id =
+      problem_.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+  problem_.SetParameterBlockConstant(x_);
+  problem_.SetParameterBlockConstant(y_);
+
+  Vector expected_f(5);
+  expected_f << 1, 2, 1, 2, 3;
+  double expected_cost = expected_f.squaredNorm() / 2.0;
+
+  double actual_cost;
+  Vector actual_f(5);
+  Matrix actual_dfdx(5, 2);
+  Matrix actual_dfdy(5, 3);
+
+  // Try evaluating with one or more Jacobians, this should fail.
+  double* jacobians[2] = {actual_dfdx.data(), actual_dfdy.data()};
+  EXPECT_FALSE(problem_.EvaluateResidualBlock(residual_block_id,
+                                              kApplyLossFunction,
+                                              kNewPoint,
+                                              &actual_cost,
+                                              actual_f.data(),
+                                              jacobians));
+
+  jacobians[0] = nullptr;
+  EXPECT_FALSE(problem_.EvaluateResidualBlock(residual_block_id,
+                                              kApplyLossFunction,
+                                              kNewPoint,
+                                              &actual_cost,
+                                              actual_f.data(),
+                                              jacobians));
+  jacobians[1] = nullptr;
+  EXPECT_TRUE(problem_.EvaluateResidualBlock(residual_block_id,
+                                             kApplyLossFunction,
+                                             kNewPoint,
+                                             &actual_cost,
+                                             actual_f.data(),
+                                             jacobians));
+
+  EXPECT_NEAR(std::abs(expected_cost - actual_cost) / actual_cost,
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_cost;
+  EXPECT_NEAR((expected_f - actual_f).norm() / actual_f.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_f;
+}
+
+TEST_F(ProblemEvaluateResidualBlockTest,
+       OneResidualBlockWithOneParameterBlockConstantAndParameterBlockChanged) {
+  ResidualBlockId residual_block_id =
+      problem_.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+  problem_.SetParameterBlockConstant(x_);
+
+  x_[0] = 2;
+  y_[2] = 1;
+  Vector expected_f(5);
+  expected_f << 2, 2, 1, 2, 1;
+  Matrix expected_dfdy = Matrix::Zero(5, 3);
+  expected_dfdy.block(2, 0, 3, 3) = Matrix::Identity(3, 3);
+  double expected_cost = expected_f.squaredNorm() / 2.0;
+
+  double actual_cost;
+  Vector actual_f(5);
+  Matrix actual_dfdx(5, 2);
+  Matrix actual_dfdy(5, 3);
+
+  // Try evaluating with one or more Jacobians, this should fail.
+  double* jacobians[2] = {actual_dfdx.data(), actual_dfdy.data()};
+  EXPECT_FALSE(problem_.EvaluateResidualBlock(residual_block_id,
+                                              kApplyLossFunction,
+                                              kNewPoint,
+                                              &actual_cost,
+                                              actual_f.data(),
+                                              jacobians));
+
+  jacobians[0] = nullptr;
+  EXPECT_TRUE(problem_.EvaluateResidualBlock(residual_block_id,
+                                             kApplyLossFunction,
+                                             kNewPoint,
+                                             &actual_cost,
+                                             actual_f.data(),
+                                             jacobians));
+  EXPECT_NEAR(std::abs(expected_cost - actual_cost) / actual_cost,
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_cost;
+  EXPECT_NEAR((expected_f - actual_f).norm() / actual_f.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_f;
+  EXPECT_NEAR((expected_dfdy - actual_dfdy).norm() / actual_dfdy.norm(),
+              0,
+              std::numeric_limits<double>::epsilon())
+      << actual_dfdy;
+}
+
 TEST(Problem, SetAndGetParameterLowerBound) {
   Problem problem;
   double x[] = {1.0, 2.0};
@@ -1582,5 +2139,145 @@
             std::numeric_limits<double>::max());
 }
 
+TEST(Problem, SetParameterizationTwice) {
+  Problem problem;
+  double x[] = {1.0, 2.0, 3.0};
+  problem.AddParameterBlock(x, 3);
+  problem.SetParameterization(x, new SubsetParameterization(3, {1}));
+  EXPECT_EQ(problem.GetParameterization(x)->GlobalSize(), 3);
+  EXPECT_EQ(problem.GetParameterization(x)->LocalSize(), 2);
+
+  problem.SetParameterization(x, new SubsetParameterization(3, {0, 1}));
+  EXPECT_EQ(problem.GetParameterization(x)->GlobalSize(), 3);
+  EXPECT_EQ(problem.GetParameterization(x)->LocalSize(), 1);
+}
+
+TEST(Problem, SetParameterizationAndThenClearItWithNull) {
+  Problem problem;
+  double x[] = {1.0, 2.0, 3.0};
+  problem.AddParameterBlock(x, 3);
+  problem.SetParameterization(x, new SubsetParameterization(3, {1}));
+  EXPECT_EQ(problem.GetParameterization(x)->GlobalSize(), 3);
+  EXPECT_EQ(problem.GetParameterization(x)->LocalSize(), 2);
+
+  problem.SetParameterization(x, nullptr);
+  EXPECT_EQ(problem.GetParameterization(x), nullptr);
+  EXPECT_EQ(problem.ParameterBlockLocalSize(x), 3);
+  EXPECT_EQ(problem.ParameterBlockSize(x), 3);
+}
+
+TEST(Solver, ZeroSizedLocalParameterizationMeansParameterBlockIsConstant) {
+  double x = 0.0;
+  double y = 1.0;
+  Problem problem;
+  problem.AddResidualBlock(new BinaryCostFunction(1, 1, 1), nullptr, &x, &y);
+  problem.SetParameterization(&y, new SubsetParameterization(1, {0}));
+  EXPECT_TRUE(problem.IsParameterBlockConstant(&y));
+}
+
+class MockEvaluationCallback : public EvaluationCallback {
+ public:
+  MOCK_METHOD2(PrepareForEvaluation, void(bool, bool));
+};
+
+TEST(ProblemEvaluate, CallsEvaluationCallbackWithoutJacobian) {
+  constexpr bool kDoNotComputeJacobians = false;
+  constexpr bool kNewPoint = true;
+
+  MockEvaluationCallback evaluation_callback;
+  EXPECT_CALL(evaluation_callback,
+              PrepareForEvaluation(kDoNotComputeJacobians, kNewPoint))
+      .Times(1);
+
+  Problem::Options options;
+  options.evaluation_callback = &evaluation_callback;
+  ProblemImpl problem(options);
+  double x_[2] = {1, 2};
+  double y_[3] = {1, 2, 3};
+  problem.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+
+  double actual_cost;
+  EXPECT_TRUE(problem.Evaluate(
+      Problem::EvaluateOptions(), &actual_cost, nullptr, nullptr, nullptr));
+}
+
+TEST(ProblemEvaluate, CallsEvaluationCallbackWithJacobian) {
+  constexpr bool kComputeJacobians = true;
+  constexpr bool kNewPoint = true;
+
+  MockEvaluationCallback evaluation_callback;
+  EXPECT_CALL(evaluation_callback,
+              PrepareForEvaluation(kComputeJacobians, kNewPoint))
+      .Times(1);
+
+  Problem::Options options;
+  options.evaluation_callback = &evaluation_callback;
+  ProblemImpl problem(options);
+  double x_[2] = {1, 2};
+  double y_[3] = {1, 2, 3};
+  problem.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+
+  double actual_cost;
+  ceres::CRSMatrix jacobian;
+  EXPECT_TRUE(problem.Evaluate(
+      Problem::EvaluateOptions(), &actual_cost, nullptr, nullptr, &jacobian));
+}
+
+TEST(ProblemEvaluateResidualBlock, NewPointCallsEvaluationCallback) {
+  constexpr bool kComputeJacobians = true;
+  constexpr bool kNewPoint = true;
+
+  MockEvaluationCallback evaluation_callback;
+  EXPECT_CALL(evaluation_callback,
+              PrepareForEvaluation(kComputeJacobians, kNewPoint))
+      .Times(1);
+
+  Problem::Options options;
+  options.evaluation_callback = &evaluation_callback;
+  ProblemImpl problem(options);
+  double x_[2] = {1, 2};
+  double y_[3] = {1, 2, 3};
+  ResidualBlockId residual_block_id =
+      problem.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+
+  double actual_cost;
+  Vector actual_f(5);
+  Matrix actual_dfdx(5, 2);
+  Matrix actual_dfdy(5, 3);
+  double* jacobians[2] = {actual_dfdx.data(), actual_dfdy.data()};
+  EXPECT_TRUE(problem.EvaluateResidualBlock(
+      residual_block_id, true, true, &actual_cost, actual_f.data(), jacobians));
+}
+
+TEST(ProblemEvaluateResidualBlock, OldPointCallsEvaluationCallback) {
+  constexpr bool kComputeJacobians = true;
+  constexpr bool kOldPoint = false;
+
+  MockEvaluationCallback evaluation_callback;
+  EXPECT_CALL(evaluation_callback,
+              PrepareForEvaluation(kComputeJacobians, kOldPoint))
+      .Times(1);
+
+  Problem::Options options;
+  options.evaluation_callback = &evaluation_callback;
+  ProblemImpl problem(options);
+  double x_[2] = {1, 2};
+  double y_[3] = {1, 2, 3};
+  ResidualBlockId residual_block_id =
+      problem.AddResidualBlock(IdentityFunctor::Create(), nullptr, x_, y_);
+
+  double actual_cost;
+  Vector actual_f(5);
+  Matrix actual_dfdx(5, 2);
+  Matrix actual_dfdy(5, 3);
+  double* jacobians[2] = {actual_dfdx.data(), actual_dfdy.data()};
+  EXPECT_TRUE(problem.EvaluateResidualBlock(residual_block_id,
+                                            true,
+                                            false,
+                                            &actual_cost,
+                                            actual_f.data(),
+                                            jacobians));
+}
+
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/program.cc b/internal/ceres/program.cc
index f1cd1bb..f1ded2e 100644
--- a/internal/ceres/program.cc
+++ b/internal/ceres/program.cc
@@ -62,8 +62,8 @@
 
 Program::Program(const Program& program)
     : parameter_blocks_(program.parameter_blocks_),
-      residual_blocks_(program.residual_blocks_) {
-}
+      residual_blocks_(program.residual_blocks_),
+      evaluation_callback_(program.evaluation_callback_) {}
 
 const vector<ParameterBlock*>& Program::parameter_blocks() const {
   return parameter_blocks_;
@@ -81,7 +81,11 @@
   return &residual_blocks_;
 }
 
-bool Program::StateVectorToParameterBlocks(const double *state) {
+EvaluationCallback* Program::mutable_evaluation_callback() {
+  return evaluation_callback_;
+}
+
+bool Program::StateVectorToParameterBlocks(const double* state) {
   for (int i = 0; i < parameter_blocks_.size(); ++i) {
     if (!parameter_blocks_[i]->IsConstant() &&
         !parameter_blocks_[i]->SetState(state)) {
@@ -92,7 +96,7 @@
   return true;
 }
 
-void Program::ParameterBlocksToStateVector(double *state) const {
+void Program::ParameterBlocksToStateVector(double* state) const {
   for (int i = 0; i < parameter_blocks_.size(); ++i) {
     parameter_blocks_[i]->GetState(state);
     state += parameter_blocks_[i]->Size();
@@ -192,7 +196,9 @@
           "ParameterBlock: %p with size %d has at least one invalid value.\n"
           "First invalid value is at index: %d.\n"
           "Parameter block values: ",
-          array, size, invalid_index);
+          array,
+          size,
+          invalid_index);
       AppendArrayToString(size, array, message);
       return false;
     }
@@ -239,7 +245,12 @@
               "\nFirst infeasible value is at index: %d."
               "\nLower bound: %e, value: %e, upper bound: %e"
               "\nParameter block values: ",
-              parameters, size, j, lower_bound, parameters[j], upper_bound);
+              parameters,
+              size,
+              j,
+              lower_bound,
+              parameters[j],
+              upper_bound);
           AppendArrayToString(size, parameters, message);
           return false;
         }
@@ -258,7 +269,11 @@
               "\nFirst infeasible bound is at index: %d."
               "\nLower bound: %e, upper bound: %e"
               "\nParameter block values: ",
-              parameters, size, j, lower_bound, upper_bound);
+              parameters,
+              size,
+              j,
+              lower_bound,
+              upper_bound);
           AppendArrayToString(size, parameters, message);
           return false;
         }
@@ -278,10 +293,9 @@
   CHECK(error != nullptr);
 
   std::unique_ptr<Program> reduced_program(new Program(*this));
-  if (!reduced_program->RemoveFixedBlocks(removed_parameter_blocks,
-                                          fixed_cost,
-                                          error)) {
-    return NULL;
+  if (!reduced_program->RemoveFixedBlocks(
+          removed_parameter_blocks, fixed_cost, error)) {
+    return nullptr;
   }
 
   reduced_program->SetParameterOffsetsAndIndex();
@@ -300,6 +314,8 @@
       new double[MaxScratchDoublesNeededForEvaluate()]);
   *fixed_cost = 0.0;
 
+  bool need_to_call_prepare_for_evaluation = evaluation_callback_ != nullptr;
+
   // Mark all the parameters as unused. Abuse the index member of the
   // parameter blocks for the marking.
   for (int i = 0; i < parameter_blocks_.size(); ++i) {
@@ -329,18 +345,45 @@
       continue;
     }
 
+    // This is an exceedingly rare case, where the user has residual
+    // blocks which are effectively constant but they are also
+    // performance sensitive enough to add an EvaluationCallback.
+    //
+    // In this case before we evaluate the cost of the constant
+    // residual blocks, we must call
+    // EvaluationCallback::PrepareForEvaluation(). Because this call
+    // can be costly, we only call this if we actually encounter a
+    // residual block with all constant parameter blocks.
+    //
+    // It is worth nothing that there is a minor inefficiency here,
+    // that the iteration 0 of TrustRegionMinimizer will also cause
+    // PrepareForEvaluation to be called on the same point, but with
+    // evaluate_jacobians = true. We could try and optimize this here,
+    // but given the rarity of this case, the additional complexity
+    // and long range dependency is not worth it.
+    if (need_to_call_prepare_for_evaluation) {
+      constexpr bool kNewPoint = true;
+      constexpr bool kDoNotEvaluateJacobians = false;
+      evaluation_callback_->PrepareForEvaluation(kDoNotEvaluateJacobians,
+                                                 kNewPoint);
+      need_to_call_prepare_for_evaluation = false;
+    }
+
     // The residual is constant and will be removed, so its cost is
     // added to the variable fixed_cost.
     double cost = 0.0;
     if (!residual_block->Evaluate(true,
                                   &cost,
-                                  NULL,
-                                  NULL,
+                                  nullptr,
+                                  nullptr,
                                   residual_block_evaluate_scratch.get())) {
-      *error = StringPrintf("Evaluation of the residual %d failed during "
-                            "removal of fixed residual blocks.", i);
+      *error = StringPrintf(
+          "Evaluation of the residual %d failed during "
+          "removal of fixed residual blocks.",
+          i);
       return false;
     }
+
     *fixed_cost += cost;
   }
   residual_blocks_.resize(num_active_residual_blocks);
@@ -359,11 +402,9 @@
   }
   parameter_blocks_.resize(num_active_parameter_blocks);
 
-  if (!(((NumResidualBlocks() == 0) &&
-         (NumParameterBlocks() == 0)) ||
-        ((NumResidualBlocks() != 0) &&
-         (NumParameterBlocks() != 0)))) {
-    *error =  "Congratulations, you found a bug in Ceres. Please report it.";
+  if (!(((NumResidualBlocks() == 0) && (NumParameterBlocks() == 0)) ||
+        ((NumResidualBlocks() != 0) && (NumParameterBlocks() != 0)))) {
+    *error = "Congratulations, you found a bug in Ceres. Please report it.";
     return false;
   }
 
@@ -382,8 +423,7 @@
     const int num_parameter_blocks = residual_block->NumParameterBlocks();
     int count = 0;
     for (int i = 0; i < num_parameter_blocks; ++i) {
-      count += independent_set.count(
-          parameter_blocks[i]->mutable_user_state());
+      count += independent_set.count(parameter_blocks[i]->mutable_user_state());
     }
     if (count > 1) {
       return false;
@@ -392,18 +432,20 @@
   return true;
 }
 
-TripletSparseMatrix* Program::CreateJacobianBlockSparsityTranspose() const {
+std::unique_ptr<TripletSparseMatrix>
+Program::CreateJacobianBlockSparsityTranspose(int start_residual_block) const {
   // Matrix to store the block sparsity structure of the Jacobian.
-  TripletSparseMatrix* tsm =
-      new TripletSparseMatrix(NumParameterBlocks(),
-                              NumResidualBlocks(),
-                              10 * NumResidualBlocks());
+  const int num_rows = NumParameterBlocks();
+  const int num_cols = NumResidualBlocks() - start_residual_block;
+
+  std::unique_ptr<TripletSparseMatrix> tsm(
+      new TripletSparseMatrix(num_rows, num_cols, 10 * num_cols));
   int num_nonzeros = 0;
   int* rows = tsm->mutable_rows();
   int* cols = tsm->mutable_cols();
   double* values = tsm->mutable_values();
 
-  for (int c = 0; c < residual_blocks_.size(); ++c) {
+  for (int c = start_residual_block; c < residual_blocks_.size(); ++c) {
     const ResidualBlock* residual_block = residual_blocks_[c];
     const int num_parameter_blocks = residual_block->NumParameterBlocks();
     ParameterBlock* const* parameter_blocks =
@@ -425,7 +467,7 @@
 
       const int r = parameter_blocks[j]->index();
       rows[num_nonzeros] = r;
-      cols[num_nonzeros] = c;
+      cols[num_nonzeros] = c - start_residual_block;
       values[num_nonzeros] = 1.0;
       ++num_nonzeros;
     }
@@ -435,13 +477,9 @@
   return tsm;
 }
 
-int Program::NumResidualBlocks() const {
-  return residual_blocks_.size();
-}
+int Program::NumResidualBlocks() const { return residual_blocks_.size(); }
 
-int Program::NumParameterBlocks() const {
-  return parameter_blocks_.size();
-}
+int Program::NumParameterBlocks() const { return parameter_blocks_.size(); }
 
 int Program::NumResiduals() const {
   int num_residuals = 0;
@@ -467,6 +505,9 @@
   return num_parameters;
 }
 
+// TODO(sameeragarwal): The following methods should just be updated
+// incrementally and the values cached, rather than the linear
+// complexity we have right now on every call.
 int Program::MaxScratchDoublesNeededForEvaluate() const {
   // Compute the scratch space needed for evaluate.
   int max_scratch_bytes_for_evaluate = 0;
@@ -496,8 +537,8 @@
 int Program::MaxParametersPerResidualBlock() const {
   int max_parameters = 0;
   for (int i = 0; i < residual_blocks_.size(); ++i) {
-    max_parameters = max(max_parameters,
-                         residual_blocks_[i]->NumParameterBlocks());
+    max_parameters =
+        max(max_parameters, residual_blocks_[i]->NumParameterBlocks());
   }
   return max_parameters;
 }
@@ -516,8 +557,8 @@
   ret += StringPrintf("Number of parameters: %d\n", NumParameters());
   ret += "Parameters:\n";
   for (int i = 0; i < parameter_blocks_.size(); ++i) {
-    ret += StringPrintf("%d: %s\n",
-                        i, parameter_blocks_[i]->ToString().c_str());
+    ret +=
+        StringPrintf("%d: %s\n", i, parameter_blocks_[i]->ToString().c_str());
   }
   return ret;
 }
diff --git a/internal/ceres/program.h b/internal/ceres/program.h
index 38c958f..ca29d31 100644
--- a/internal/ceres/program.h
+++ b/internal/ceres/program.h
@@ -31,9 +31,12 @@
 #ifndef CERES_INTERNAL_PROGRAM_H_
 #define CERES_INTERNAL_PROGRAM_H_
 
+#include <memory>
 #include <set>
 #include <string>
 #include <vector>
+
+#include "ceres/evaluation_callback.h"
 #include "ceres/internal/port.h"
 
 namespace ceres {
@@ -54,7 +57,7 @@
 // another; for example, the first stage of solving involves stripping all
 // constant parameters and residuals. This is in contrast with Problem, which is
 // not built for transformation.
-class Program {
+class CERES_EXPORT_INTERNAL Program {
  public:
   Program();
   explicit Program(const Program& program);
@@ -64,6 +67,7 @@
   const std::vector<ResidualBlock*>& residual_blocks() const;
   std::vector<ParameterBlock*>* mutable_parameter_blocks();
   std::vector<ResidualBlock*>* mutable_residual_blocks();
+  EvaluationCallback* mutable_evaluation_callback();
 
   // Serialize to/from the program and update states.
   //
@@ -71,8 +75,8 @@
   // computation of the Jacobian of its local parameterization. If
   // this computation fails for some reason, then this method returns
   // false and the state of the parameter blocks cannot be trusted.
-  bool StateVectorToParameterBlocks(const double *state);
-  void ParameterBlocksToStateVector(double *state) const;
+  bool StateVectorToParameterBlocks(const double* state);
+  void ParameterBlocksToStateVector(double* state) const;
 
   // Copy internal state to the user's parameters.
   void CopyParameterBlockStateToUserState();
@@ -127,8 +131,10 @@
   // structure corresponding to the block sparsity of the transpose of
   // the Jacobian matrix.
   //
-  // Caller owns the result.
-  TripletSparseMatrix* CreateJacobianBlockSparsityTranspose() const;
+  // start_residual_block which allows the user to ignore the first
+  // start_residual_block residuals.
+  std::unique_ptr<TripletSparseMatrix> CreateJacobianBlockSparsityTranspose(
+      int start_residual_block = 0) const;
 
   // Create a copy of this program and removes constant parameter
   // blocks and residual blocks with no varying parameter blocks while
@@ -182,6 +188,7 @@
   // The Program does not own the ParameterBlock or ResidualBlock objects.
   std::vector<ParameterBlock*> parameter_blocks_;
   std::vector<ResidualBlock*> residual_blocks_;
+  EvaluationCallback* evaluation_callback_ = nullptr;
 
   friend class ProblemImpl;
 };
diff --git a/internal/ceres/program_evaluator.h b/internal/ceres/program_evaluator.h
index 6781eb7..36c9c64 100644
--- a/internal/ceres/program_evaluator.h
+++ b/internal/ceres/program_evaluator.h
@@ -43,7 +43,7 @@
 // residual jacobians are written directly into their final position in the
 // block sparse matrix by the user's CostFunction; there is no copying.
 //
-// The evaluation is threaded with OpenMP or C++11 threads.
+// The evaluation is threaded with OpenMP or C++ threads.
 //
 // The EvaluatePreparer and JacobianWriter interfaces are as follows:
 //
@@ -80,7 +80,9 @@
 #define CERES_INTERNAL_PROGRAM_EVALUATOR_H_
 
 // This include must come before any #ifndef check on Ceres compile options.
+// clang-format off
 #include "ceres/internal/port.h"
+// clang-format on
 
 #include <atomic>
 #include <map>
@@ -104,12 +106,12 @@
   void operator()(SparseMatrix* jacobian, int num_parameters) {}
 };
 
-template<typename EvaluatePreparer,
-         typename JacobianWriter,
-         typename JacobianFinalizer = NullJacobianFinalizer>
+template <typename EvaluatePreparer,
+          typename JacobianWriter,
+          typename JacobianFinalizer = NullJacobianFinalizer>
 class ProgramEvaluator : public Evaluator {
  public:
-  ProgramEvaluator(const Evaluator::Options &options, Program* program)
+  ProgramEvaluator(const Evaluator::Options& options, Program* program)
       : options_(options),
         program_(program),
         jacobian_writer_(options, program),
@@ -117,21 +119,20 @@
             jacobian_writer_.CreateEvaluatePreparers(options.num_threads)) {
 #ifdef CERES_NO_THREADS
     if (options_.num_threads > 1) {
-      LOG(WARNING)
-          << "No threading support is compiled into this binary; "
-          << "only options.num_threads = 1 is supported. Switching "
-          << "to single threaded mode.";
+      LOG(WARNING) << "No threading support is compiled into this binary; "
+                   << "only options.num_threads = 1 is supported. Switching "
+                   << "to single threaded mode.";
       options_.num_threads = 1;
     }
-#endif // CERES_NO_THREADS
+#endif  // CERES_NO_THREADS
 
     BuildResidualLayout(*program, &residual_layout_);
-    evaluate_scratch_.reset(CreateEvaluatorScratch(*program,
-                                                   options.num_threads));
+    evaluate_scratch_.reset(
+        CreateEvaluatorScratch(*program, options.num_threads));
   }
 
   // Implementation of Evaluator interface.
-  SparseMatrix* CreateJacobian() const {
+  SparseMatrix* CreateJacobian() const final {
     return jacobian_writer_.CreateJacobian();
   }
 
@@ -140,12 +141,12 @@
                 double* cost,
                 double* residuals,
                 double* gradient,
-                SparseMatrix* jacobian) {
+                SparseMatrix* jacobian) final {
     ScopedExecutionTimer total_timer("Evaluator::Total", &execution_summary_);
-    ScopedExecutionTimer call_type_timer(gradient == NULL && jacobian == NULL
-                                         ? "Evaluator::Residual"
-                                         : "Evaluator::Jacobian",
-                                         &execution_summary_);
+    ScopedExecutionTimer call_type_timer(
+        gradient == nullptr && jacobian == nullptr ? "Evaluator::Residual"
+                                                   : "Evaluator::Jacobian",
+        &execution_summary_);
 
     // The parameters are stateful, so set the state before evaluating.
     if (!program_->StateVectorToParameterBlocks(state)) {
@@ -153,27 +154,28 @@
     }
 
     // Notify the user about a new evaluation point if they are interested.
-    if (options_.evaluation_callback != NULL) {
+    if (options_.evaluation_callback != nullptr) {
       program_->CopyParameterBlockStateToUserState();
       options_.evaluation_callback->PrepareForEvaluation(
-          /*jacobians=*/(gradient != NULL || jacobian != NULL),
+          /*jacobians=*/(gradient != nullptr || jacobian != nullptr),
           evaluate_options.new_evaluation_point);
     }
 
-    if (residuals != NULL) {
+    if (residuals != nullptr) {
       VectorRef(residuals, program_->NumResiduals()).setZero();
     }
 
-    if (jacobian != NULL) {
+    if (jacobian != nullptr) {
       jacobian->SetZero();
     }
 
     // Each thread gets it's own cost and evaluate scratch space.
     for (int i = 0; i < options_.num_threads; ++i) {
       evaluate_scratch_[i].cost = 0.0;
-      if (gradient != NULL) {
+      if (gradient != nullptr) {
         VectorRef(evaluate_scratch_[i].gradient.get(),
-                  program_->NumEffectiveParameters()).setZero();
+                  program_->NumEffectiveParameters())
+            .setZero();
       }
     }
 
@@ -197,16 +199,16 @@
 
           // Prepare block residuals if requested.
           const ResidualBlock* residual_block = program_->residual_blocks()[i];
-          double* block_residuals = NULL;
-          if (residuals != NULL) {
+          double* block_residuals = nullptr;
+          if (residuals != nullptr) {
             block_residuals = residuals + residual_layout_[i];
-          } else if (gradient != NULL) {
+          } else if (gradient != nullptr) {
             block_residuals = scratch->residual_block_residuals.get();
           }
 
           // Prepare block jacobians if requested.
-          double** block_jacobians = NULL;
-          if (jacobian != NULL || gradient != NULL) {
+          double** block_jacobians = nullptr;
+          if (jacobian != nullptr || gradient != nullptr) {
             preparer->Prepare(residual_block,
                               i,
                               jacobian,
@@ -229,15 +231,13 @@
           scratch->cost += block_cost;
 
           // Store the jacobians, if they were requested.
-          if (jacobian != NULL) {
-            jacobian_writer_.Write(i,
-                                   residual_layout_[i],
-                                   block_jacobians,
-                                   jacobian);
+          if (jacobian != nullptr) {
+            jacobian_writer_.Write(
+                i, residual_layout_[i], block_jacobians, jacobian);
           }
 
           // Compute and store the gradient, if it was requested.
-          if (gradient != NULL) {
+          if (gradient != nullptr) {
             int num_residuals = residual_block->NumResiduals();
             int num_parameter_blocks = residual_block->NumParameterBlocks();
             for (int j = 0; j < num_parameter_blocks; ++j) {
@@ -262,12 +262,12 @@
 
       // Sum the cost and gradient (if requested) from each thread.
       (*cost) = 0.0;
-      if (gradient != NULL) {
+      if (gradient != nullptr) {
         VectorRef(gradient, num_parameters).setZero();
       }
       for (int i = 0; i < options_.num_threads; ++i) {
         (*cost) += evaluate_scratch_[i].cost;
-        if (gradient != NULL) {
+        if (gradient != nullptr) {
           VectorRef(gradient, num_parameters) +=
               VectorRef(evaluate_scratch_[i].gradient.get(), num_parameters);
         }
@@ -277,7 +277,7 @@
       // `num_parameters` is passed to the finalizer so that additional
       // storage can be reserved for additional diagonal elements if
       // necessary.
-      if (jacobian != NULL) {
+      if (jacobian != nullptr) {
         JacobianFinalizer f;
         f(jacobian, num_parameters);
       }
@@ -287,22 +287,18 @@
 
   bool Plus(const double* state,
             const double* delta,
-            double* state_plus_delta) const {
+            double* state_plus_delta) const final {
     return program_->Plus(state, delta, state_plus_delta);
   }
 
-  int NumParameters() const {
-    return program_->NumParameters();
-  }
-  int NumEffectiveParameters() const {
+  int NumParameters() const final { return program_->NumParameters(); }
+  int NumEffectiveParameters() const final {
     return program_->NumEffectiveParameters();
   }
 
-  int NumResiduals() const {
-    return program_->NumResiduals();
-  }
+  int NumResiduals() const final { return program_->NumResiduals(); }
 
-  virtual std::map<std::string, CallStatistics> Statistics() const {
+  std::map<std::string, CallStatistics> Statistics() const final {
     return execution_summary_.statistics();
   }
 
@@ -319,8 +315,7 @@
       VectorRef(gradient.get(), num_parameters).setZero();
       residual_block_residuals.reset(
           new double[max_residuals_per_residual_block]);
-      jacobian_block_ptrs.reset(
-          new double*[max_parameters_per_residual_block]);
+      jacobian_block_ptrs.reset(new double*[max_parameters_per_residual_block]);
     }
 
     double cost;
diff --git a/internal/ceres/program_test.cc b/internal/ceres/program_test.cc
index 6cb8e9e..1d9f49c 100644
--- a/internal/ceres/program_test.cc
+++ b/internal/ceres/program_test.cc
@@ -33,6 +33,7 @@
 #include <cmath>
 #include <limits>
 #include <memory>
+#include <utility>
 #include <vector>
 
 #include "ceres/internal/integer_sequence_algorithm.h"
@@ -51,9 +52,9 @@
 // A cost function that simply returns its argument.
 class UnaryIdentityCostFunction : public SizedCostFunction<1, 1> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     residuals[0] = parameters[0][0];
     if (jacobians != nullptr && jacobians[0] != nullptr) {
       jacobians[0][0] = 1.0;
@@ -66,10 +67,10 @@
 template <int kNumResiduals, int... Ns>
 class MockCostFunctionBase : public SizedCostFunction<kNumResiduals, Ns...> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
-    const int kNumParameters = Sum<integer_sequence<int, Ns...>>::Value;
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
+    const int kNumParameters = Sum<std::integer_sequence<int, Ns...>>::Value;
 
     for (int i = 0; i < kNumResiduals; ++i) {
       residuals[i] = kNumResiduals + kNumParameters;
@@ -98,7 +99,8 @@
   vector<double*> removed_parameter_blocks;
   double fixed_cost = 0.0;
   string message;
-  std::unique_ptr<Program> reduced_program(problem.program().CreateReducedProgram(
+  std::unique_ptr<Program> reduced_program(
+      problem.program().CreateReducedProgram(
           &removed_parameter_blocks, &fixed_cost, &message));
 
   EXPECT_EQ(reduced_program->NumParameterBlocks(), 3);
@@ -129,7 +131,6 @@
   EXPECT_EQ(fixed_cost, 9.0);
 }
 
-
 TEST(Program, RemoveFixedBlocksNoResidualBlocks) {
   ProblemImpl problem;
   double x;
@@ -214,17 +215,13 @@
   problem.AddResidualBlock(new BinaryCostFunction(), nullptr, &x, &y);
   problem.SetParameterBlockConstant(&x);
 
-  ResidualBlock *expected_removed_block =
+  ResidualBlock* expected_removed_block =
       problem.program().residual_blocks()[0];
   std::unique_ptr<double[]> scratch(
       new double[expected_removed_block->NumScratchDoublesForEvaluate()]);
   double expected_fixed_cost;
-  expected_removed_block->Evaluate(true,
-                                   &expected_fixed_cost,
-                                   nullptr,
-                                   nullptr,
-                                   scratch.get());
-
+  expected_removed_block->Evaluate(
+      true, &expected_fixed_cost, nullptr, nullptr, scratch.get());
 
   vector<double*> removed_parameter_blocks;
   double fixed_cost = 0.0;
@@ -238,7 +235,9 @@
   EXPECT_DOUBLE_EQ(fixed_cost, expected_fixed_cost);
 }
 
-TEST(Program, CreateJacobianBlockSparsityTranspose) {
+class BlockJacobianTest : public ::testing::TestWithParam<int> {};
+
+TEST_P(BlockJacobianTest, CreateJacobianBlockSparsityTranspose) {
   ProblemImpl problem;
   double x[2];
   double y[3];
@@ -304,17 +303,24 @@
   Program* program = problem.mutable_program();
   program->SetParameterOffsetsAndIndex();
 
+  const int start_row_block = GetParam();
   std::unique_ptr<TripletSparseMatrix> actual_block_sparse_jacobian(
-      program->CreateJacobianBlockSparsityTranspose());
+      program->CreateJacobianBlockSparsityTranspose(start_row_block));
 
-  Matrix expected_dense_jacobian;
-  expected_block_sparse_jacobian.ToDenseMatrix(&expected_dense_jacobian);
+  Matrix expected_full_dense_jacobian;
+  expected_block_sparse_jacobian.ToDenseMatrix(&expected_full_dense_jacobian);
+  Matrix expected_dense_jacobian =
+      expected_full_dense_jacobian.rightCols(8 - start_row_block);
 
   Matrix actual_dense_jacobian;
   actual_block_sparse_jacobian->ToDenseMatrix(&actual_dense_jacobian);
+  EXPECT_EQ(expected_dense_jacobian.rows(), actual_dense_jacobian.rows());
+  EXPECT_EQ(expected_dense_jacobian.cols(), actual_dense_jacobian.cols());
   EXPECT_EQ((expected_dense_jacobian - actual_dense_jacobian).norm(), 0.0);
 }
 
+INSTANTIATE_TEST_SUITE_P(AllColumns, BlockJacobianTest, ::testing::Range(0, 7));
+
 template <int kNumResiduals, int kNumParameterBlocks>
 class NumParameterBlocksCostFunction : public CostFunction {
  public:
@@ -325,12 +331,11 @@
     }
   }
 
-  virtual ~NumParameterBlocksCostFunction() {
-  }
+  virtual ~NumParameterBlocksCostFunction() {}
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     return true;
   }
 };
@@ -391,8 +396,8 @@
   problem.AddResidualBlock(new MockCostFunctionBase<1, 2>(), nullptr, x);
   string error;
   EXPECT_FALSE(problem.program().ParameterBlocksAreFinite(&error));
-  EXPECT_NE(error.find("has at least one invalid value"),
-            string::npos) << error;
+  EXPECT_NE(error.find("has at least one invalid value"), string::npos)
+      << error;
 }
 
 TEST(Program, InfeasibleParameterBlock) {
diff --git a/internal/ceres/random.h b/internal/ceres/random.h
index 87d9d77..6b280f9 100644
--- a/internal/ceres/random.h
+++ b/internal/ceres/random.h
@@ -34,13 +34,12 @@
 
 #include <cmath>
 #include <cstdlib>
+
 #include "ceres/internal/port.h"
 
 namespace ceres {
 
-inline void SetRandomState(int state) {
-  srand(state);
-}
+inline void SetRandomState(int state) { srand(state); }
 
 inline int Uniform(int n) {
   if (n) {
@@ -63,7 +62,7 @@
     x1 = 2.0 * RandDouble() - 1.0;
     x2 = 2.0 * RandDouble() - 1.0;
     w = x1 * x1 + x2 * x2;
-  } while ( w >= 1.0 || w == 0.0 );
+  } while (w >= 1.0 || w == 0.0);
 
   w = sqrt((-2.0 * log(w)) / w);
   return x1 * w;
diff --git a/internal/ceres/reorder_program.cc b/internal/ceres/reorder_program.cc
index 5a3fbfd..5d80236 100644
--- a/internal/ceres/reorder_program.cc
+++ b/internal/ceres/reorder_program.cc
@@ -35,6 +35,7 @@
 #include <numeric>
 #include <vector>
 
+#include "Eigen/SparseCore"
 #include "ceres/cxsparse.h"
 #include "ceres/internal/port.h"
 #include "ceres/ordered_groups.h"
@@ -47,7 +48,6 @@
 #include "ceres/suitesparse.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
-#include "Eigen/SparseCore"
 
 #ifdef CERES_USE_EIGEN_SPARSE
 #include "Eigen/OrderingMethods"
@@ -78,14 +78,14 @@
       CHECK_NE(parameter_block->index(), -1)
           << "Did you forget to call Program::SetParameterOffsetsAndIndex()? "
           << "This is a Ceres bug; please contact the developers!";
-      min_parameter_block_position = std::min(parameter_block->index(),
-                                              min_parameter_block_position);
+      min_parameter_block_position =
+          std::min(parameter_block->index(), min_parameter_block_position);
     }
   }
   return min_parameter_block_position;
 }
 
-#if EIGEN_VERSION_AT_LEAST(3, 2, 2) && defined(CERES_USE_EIGEN_SPARSE)
+#if defined(CERES_USE_EIGEN_SPARSE)
 Eigen::SparseMatrix<int> CreateBlockJacobian(
     const TripletSparseMatrix& block_jacobian_transpose) {
   typedef Eigen::SparseMatrix<int> SparseMatrix;
@@ -117,9 +117,8 @@
              << "Please report this error to the developers.";
 #else
   SuiteSparse ss;
-  cholmod_sparse* block_jacobian_transpose =
-      ss.CreateSparseMatrix(
-          const_cast<TripletSparseMatrix*>(&tsm_block_jacobian_transpose));
+  cholmod_sparse* block_jacobian_transpose = ss.CreateSparseMatrix(
+      const_cast<TripletSparseMatrix*>(&tsm_block_jacobian_transpose));
 
   // No CAMD or the user did not supply a useful ordering, then just
   // use regular AMD.
@@ -129,18 +128,16 @@
   } else {
     vector<int> constraints;
     for (int i = 0; i < parameter_blocks.size(); ++i) {
-      constraints.push_back(
-          parameter_block_ordering.GroupId(
-              parameter_blocks[i]->mutable_user_state()));
+      constraints.push_back(parameter_block_ordering.GroupId(
+          parameter_blocks[i]->mutable_user_state()));
     }
 
     // Renumber the entries of constraints to be contiguous integers
     // as CAMD requires that the group ids be in the range [0,
     // parameter_blocks.size() - 1].
     MapValuesToContiguousRange(constraints.size(), &constraints[0]);
-    ss.ConstrainedApproximateMinimumDegreeOrdering(block_jacobian_transpose,
-                                                   &constraints[0],
-                                                   ordering);
+    ss.ConstrainedApproximateMinimumDegreeOrdering(
+        block_jacobian_transpose, &constraints[0], ordering);
   }
 
   VLOG(2) << "Block ordering stats: "
@@ -153,20 +150,18 @@
 }
 
 void OrderingForSparseNormalCholeskyUsingCXSparse(
-    const TripletSparseMatrix& tsm_block_jacobian_transpose,
-    int* ordering) {
+    const TripletSparseMatrix& tsm_block_jacobian_transpose, int* ordering) {
 #ifdef CERES_NO_CXSPARSE
   LOG(FATAL) << "Congratulations, you found a Ceres bug! "
              << "Please report this error to the developers.";
-#else  // CERES_NO_CXSPARSE
+#else
   // CXSparse works with J'J instead of J'. So compute the block
   // sparsity for J'J and compute an approximate minimum degree
   // ordering.
   CXSparse cxsparse;
   cs_di* block_jacobian_transpose;
-  block_jacobian_transpose =
-      cxsparse.CreateSparseMatrix(
-            const_cast<TripletSparseMatrix*>(&tsm_block_jacobian_transpose));
+  block_jacobian_transpose = cxsparse.CreateSparseMatrix(
+      const_cast<TripletSparseMatrix*>(&tsm_block_jacobian_transpose));
   cs_di* block_jacobian = cxsparse.TransposeMatrix(block_jacobian_transpose);
   cs_di* block_hessian =
       cxsparse.MatrixMatrixMultiply(block_jacobian_transpose, block_jacobian);
@@ -178,17 +173,13 @@
 #endif  // CERES_NO_CXSPARSE
 }
 
-
-#if EIGEN_VERSION_AT_LEAST(3, 2, 2)
 void OrderingForSparseNormalCholeskyUsingEigenSparse(
-    const TripletSparseMatrix& tsm_block_jacobian_transpose,
-    int* ordering) {
+    const TripletSparseMatrix& tsm_block_jacobian_transpose, int* ordering) {
 #ifndef CERES_USE_EIGEN_SPARSE
-  LOG(FATAL) <<
-      "SPARSE_NORMAL_CHOLESKY cannot be used with EIGEN_SPARSE "
-      "because Ceres was not built with support for "
-      "Eigen's SimplicialLDLT decomposition. "
-      "This requires enabling building with -DEIGENSPARSE=ON.";
+  LOG(FATAL) << "SPARSE_NORMAL_CHOLESKY cannot be used with EIGEN_SPARSE "
+                "because Ceres was not built with support for "
+                "Eigen's SimplicialLDLT decomposition. "
+                "This requires enabling building with -DEIGENSPARSE=ON.";
 #else
 
   // This conversion from a TripletSparseMatrix to a Eigen::Triplet
@@ -212,7 +203,6 @@
   }
 #endif  // CERES_USE_EIGEN_SPARSE
 }
-#endif
 
 }  // namespace
 
@@ -220,13 +210,14 @@
                    const ParameterBlockOrdering& ordering,
                    Program* program,
                    string* error) {
-  const int num_parameter_blocks =  program->NumParameterBlocks();
+  const int num_parameter_blocks = program->NumParameterBlocks();
   if (ordering.NumElements() != num_parameter_blocks) {
-    *error = StringPrintf("User specified ordering does not have the same "
-                          "number of parameters as the problem. The problem"
-                          "has %d blocks while the ordering has %d blocks.",
-                          num_parameter_blocks,
-                          ordering.NumElements());
+    *error = StringPrintf(
+        "User specified ordering does not have the same "
+        "number of parameters as the problem. The problem"
+        "has %d blocks while the ordering has %d blocks.",
+        num_parameter_blocks,
+        ordering.NumElements());
     return false;
   }
 
@@ -240,10 +231,11 @@
     for (double* parameter_block_ptr : group) {
       auto it = parameter_map.find(parameter_block_ptr);
       if (it == parameter_map.end()) {
-        *error = StringPrintf("User specified ordering contains a pointer "
-                              "to a double that is not a parameter block in "
-                              "the problem. The invalid double is in group: %d",
-                              p.first);
+        *error = StringPrintf(
+            "User specified ordering contains a pointer "
+            "to a double that is not a parameter block in "
+            "the problem. The invalid double is in group: %d",
+            p.first);
         return false;
       }
       parameter_blocks->push_back(it->second);
@@ -267,8 +259,8 @@
   vector<int> min_position_per_residual(residual_blocks->size());
   for (int i = 0; i < residual_blocks->size(); ++i) {
     ResidualBlock* residual_block = (*residual_blocks)[i];
-    int position = MinParameterBlock(residual_block,
-                                     size_of_first_elimination_group);
+    int position =
+        MinParameterBlock(residual_block, size_of_first_elimination_group);
     min_position_per_residual[i] = position;
     DCHECK_LE(position, size_of_first_elimination_group);
     residual_blocks_per_e_block[position]++;
@@ -286,8 +278,8 @@
       << "to the developers.";
 
   CHECK(find(residual_blocks_per_e_block.begin(),
-             residual_blocks_per_e_block.end() - 1, 0) !=
-        residual_blocks_per_e_block.end())
+             residual_blocks_per_e_block.end() - 1,
+             0) != residual_blocks_per_e_block.end())
       << "Congratulations, you found a Ceres bug! Please report this error "
       << "to the developers.";
 
@@ -335,9 +327,8 @@
 
 // Pre-order the columns corresponding to the schur complement if
 // possible.
-void MaybeReorderSchurComplementColumnsUsingSuiteSparse(
-    const ParameterBlockOrdering& parameter_block_ordering,
-    Program* program) {
+static void MaybeReorderSchurComplementColumnsUsingSuiteSparse(
+    const ParameterBlockOrdering& parameter_block_ordering, Program* program) {
 #ifndef CERES_NO_SUITESPARSE
   SuiteSparse ss;
   if (!SuiteSparse::IsConstrainedApproximateMinimumDegreeOrderingAvailable()) {
@@ -349,9 +340,8 @@
       *(program->mutable_parameter_blocks());
 
   for (int i = 0; i < parameter_blocks.size(); ++i) {
-    constraints.push_back(
-        parameter_block_ordering.GroupId(
-            parameter_blocks[i]->mutable_user_state()));
+    constraints.push_back(parameter_block_ordering.GroupId(
+        parameter_blocks[i]->mutable_user_state()));
   }
 
   // Renumber the entries of constraints to be contiguous integers as
@@ -367,9 +357,8 @@
       ss.CreateSparseMatrix(tsm_block_jacobian_transpose.get());
 
   vector<int> ordering(parameter_blocks.size(), 0);
-  ss.ConstrainedApproximateMinimumDegreeOrdering(block_jacobian_transpose,
-                                                 &constraints[0],
-                                                 &ordering[0]);
+  ss.ConstrainedApproximateMinimumDegreeOrdering(
+      block_jacobian_transpose, &constraints[0], &ordering[0]);
   ss.Free(block_jacobian_transpose);
 
   const vector<ParameterBlock*> parameter_blocks_copy(parameter_blocks);
@@ -381,14 +370,11 @@
 #endif
 }
 
-void MaybeReorderSchurComplementColumnsUsingEigen(
+static void MaybeReorderSchurComplementColumnsUsingEigen(
     const int size_of_first_elimination_group,
     const ProblemImpl::ParameterMap& parameter_map,
     Program* program) {
-#if !EIGEN_VERSION_AT_LEAST(3, 2, 2) || !defined(CERES_USE_EIGEN_SPARSE)
-  return;
-#else
-
+#if defined(CERES_USE_EIGEN_SPARSE)
   std::unique_ptr<TripletSparseMatrix> tsm_block_jacobian_transpose(
       program->CreateJacobianBlockSparsityTranspose());
 
@@ -401,10 +387,7 @@
   // Vertically partition the jacobian in parameter blocks of type E
   // and F.
   const SparseMatrix E =
-      block_jacobian.block(0,
-                           0,
-                           num_rows,
-                           size_of_first_elimination_group);
+      block_jacobian.block(0, 0, num_rows, size_of_first_elimination_group);
   const SparseMatrix F =
       block_jacobian.block(0,
                            size_of_first_elimination_group,
@@ -487,22 +470,17 @@
 
     // Verify that the first elimination group is an independent set.
     const set<double*>& first_elimination_group =
-        parameter_block_ordering
-        ->group_to_elements()
-        .begin()
-        ->second;
+        parameter_block_ordering->group_to_elements().begin()->second;
     if (!program->IsParameterBlockSetIndependent(first_elimination_group)) {
-      *error =
-          StringPrintf("The first elimination group in the parameter block "
-                       "ordering of size %zd is not an independent set",
-                       first_elimination_group.size());
+      *error = StringPrintf(
+          "The first elimination group in the parameter block "
+          "ordering of size %zd is not an independent set",
+          first_elimination_group.size());
       return false;
     }
 
-    if (!ApplyOrdering(parameter_map,
-                       *parameter_block_ordering,
-                       program,
-                       error)) {
+    if (!ApplyOrdering(
+            parameter_map, *parameter_block_ordering, program, error)) {
       return false;
     }
   }
@@ -515,30 +493,23 @@
   if (linear_solver_type == SPARSE_SCHUR) {
     if (sparse_linear_algebra_library_type == SUITE_SPARSE) {
       MaybeReorderSchurComplementColumnsUsingSuiteSparse(
-          *parameter_block_ordering,
-          program);
+          *parameter_block_ordering, program);
     } else if (sparse_linear_algebra_library_type == EIGEN_SPARSE) {
       MaybeReorderSchurComplementColumnsUsingEigen(
-          size_of_first_elimination_group,
-          parameter_map,
-          program);
+          size_of_first_elimination_group, parameter_map, program);
     }
   }
 
   // Schur type solvers also require that their residual blocks be
   // lexicographically ordered.
-  if (!LexicographicallyOrderResidualBlocks(size_of_first_elimination_group,
-                                            program,
-                                            error)) {
-    return false;
-  }
-
-  return true;
+  return LexicographicallyOrderResidualBlocks(
+      size_of_first_elimination_group, program, error);
 }
 
-bool ReorderProgramForSparseNormalCholesky(
+bool ReorderProgramForSparseCholesky(
     const SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type,
     const ParameterBlockOrdering& parameter_block_ordering,
+    int start_row_block,
     Program* program,
     string* error) {
   if (parameter_block_ordering.NumElements() != program->NumParameterBlocks()) {
@@ -552,7 +523,7 @@
 
   // Compute a block sparse presentation of J'.
   std::unique_ptr<TripletSparseMatrix> tsm_block_jacobian_transpose(
-      program->CreateJacobianBlockSparsityTranspose());
+      program->CreateJacobianBlockSparsityTranspose(start_row_block));
 
   vector<int> ordering(program->NumParameterBlocks(), 0);
   vector<ParameterBlock*>& parameter_blocks =
@@ -565,9 +536,8 @@
         parameter_block_ordering,
         &ordering[0]);
   } else if (sparse_linear_algebra_library_type == CX_SPARSE) {
-    OrderingForSparseNormalCholeskyUsingCXSparse(
-        *tsm_block_jacobian_transpose,
-        &ordering[0]);
+    OrderingForSparseNormalCholeskyUsingCXSparse(*tsm_block_jacobian_transpose,
+                                                 &ordering[0]);
   } else if (sparse_linear_algebra_library_type == ACCELERATE_SPARSE) {
     // Accelerate does not provide a function to perform reordering without
     // performing a full symbolic factorisation.  As such, we have nothing
@@ -578,18 +548,8 @@
     return true;
 
   } else if (sparse_linear_algebra_library_type == EIGEN_SPARSE) {
-#if EIGEN_VERSION_AT_LEAST(3, 2, 2)
-       OrderingForSparseNormalCholeskyUsingEigenSparse(
-        *tsm_block_jacobian_transpose,
-        &ordering[0]);
-#else
-    // For Eigen versions less than 3.2.2, there is nothing to do as
-    // older versions of Eigen do not expose a method for doing
-    // symbolic analysis on pre-ordered matrices, so a block
-    // pre-ordering is a bit pointless.
-
-    return true;
-#endif
+    OrderingForSparseNormalCholeskyUsingEigenSparse(
+        *tsm_block_jacobian_transpose, &ordering[0]);
   }
 
   // Apply ordering.
@@ -602,5 +562,17 @@
   return true;
 }
 
+int ReorderResidualBlocksByPartition(
+    const std::unordered_set<ResidualBlockId>& bottom_residual_blocks,
+    Program* program) {
+  auto residual_blocks = program->mutable_residual_blocks();
+  auto it = std::partition(residual_blocks->begin(),
+                           residual_blocks->end(),
+                           [&bottom_residual_blocks](ResidualBlock* r) {
+                             return bottom_residual_blocks.count(r) == 0;
+                           });
+  return it - residual_blocks->begin();
+}
+
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/reorder_program.h b/internal/ceres/reorder_program.h
index 36e5d16..2e0c326 100644
--- a/internal/ceres/reorder_program.h
+++ b/internal/ceres/reorder_program.h
@@ -32,6 +32,7 @@
 #define CERES_INTERNAL_REORDER_PROGRAM_H_
 
 #include <string>
+
 #include "ceres/internal/port.h"
 #include "ceres/parameter_block_ordering.h"
 #include "ceres/problem_impl.h"
@@ -43,17 +44,17 @@
 class Program;
 
 // Reorder the parameter blocks in program using the ordering
-bool ApplyOrdering(const ProblemImpl::ParameterMap& parameter_map,
-                   const ParameterBlockOrdering& ordering,
-                   Program* program,
-                   std::string* error);
+CERES_EXPORT_INTERNAL bool ApplyOrdering(
+    const ProblemImpl::ParameterMap& parameter_map,
+    const ParameterBlockOrdering& ordering,
+    Program* program,
+    std::string* error);
 
 // Reorder the residuals for program, if necessary, so that the residuals
 // involving each E block occur together. This is a necessary condition for the
 // Schur eliminator, which works on these "row blocks" in the jacobian.
-bool LexicographicallyOrderResidualBlocks(int size_of_first_elimination_group,
-                                          Program* program,
-                                          std::string* error);
+CERES_EXPORT_INTERNAL bool LexicographicallyOrderResidualBlocks(
+    int size_of_first_elimination_group, Program* program, std::string* error);
 
 // Schur type solvers require that all parameter blocks eliminated
 // by the Schur eliminator occur before others and the residuals be
@@ -71,7 +72,7 @@
 //
 // Upon return, ordering contains the parameter block ordering that
 // was used to order the program.
-bool ReorderProgramForSchurTypeLinearSolver(
+CERES_EXPORT_INTERNAL bool ReorderProgramForSchurTypeLinearSolver(
     LinearSolverType linear_solver_type,
     SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type,
     const ProblemImpl::ParameterMap& parameter_map,
@@ -89,12 +90,27 @@
 // fill-reducing ordering is available in the sparse linear algebra
 // library (SuiteSparse version >= 4.2.0) then the fill reducing
 // ordering will take it into account, otherwise it will be ignored.
-bool ReorderProgramForSparseNormalCholesky(
+CERES_EXPORT_INTERNAL bool ReorderProgramForSparseCholesky(
     SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type,
     const ParameterBlockOrdering& parameter_block_ordering,
+    int start_row_block,
     Program* program,
     std::string* error);
 
+// Reorder the residual blocks in the program so that all the residual
+// blocks in bottom_residual_blocks are at the bottom. The return
+// value is the number of residual blocks in the program in "top" part
+// of the Program, i.e., the ones not included in
+// bottom_residual_blocks.
+//
+// This number can be different from program->NumResidualBlocks() -
+// bottom_residual_blocks.size() because we allow
+// bottom_residual_blocks to contain residual blocks not present in
+// the Program.
+CERES_EXPORT_INTERNAL int ReorderResidualBlocksByPartition(
+    const std::unordered_set<ResidualBlockId>& bottom_residual_blocks,
+    Program* program);
+
 }  // namespace internal
 }  // namespace ceres
 
diff --git a/internal/ceres/reorder_program_test.cc b/internal/ceres/reorder_program_test.cc
index cf3e9f6..83c867a 100644
--- a/internal/ceres/reorder_program_test.cc
+++ b/internal/ceres/reorder_program_test.cc
@@ -30,12 +30,13 @@
 
 #include "ceres/reorder_program.h"
 
+#include <random>
+
 #include "ceres/parameter_block.h"
 #include "ceres/problem_impl.h"
 #include "ceres/program.h"
 #include "ceres/sized_cost_function.h"
 #include "ceres/solver.h"
-
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -48,9 +49,9 @@
 template <int kNumResiduals, int... Ns>
 class MockCostFunctionBase : public SizedCostFunction<kNumResiduals, Ns...> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     // Do nothing. This is never called.
     return true;
   }
@@ -70,12 +71,12 @@
   problem.AddParameterBlock(&y, 1);
   problem.AddParameterBlock(&z, 1);
 
-  problem.AddResidualBlock(new UnaryCostFunction(), NULL, &x);
-  problem.AddResidualBlock(new BinaryCostFunction(), NULL, &z, &x);
-  problem.AddResidualBlock(new BinaryCostFunction(), NULL, &z, &y);
-  problem.AddResidualBlock(new UnaryCostFunction(), NULL, &z);
-  problem.AddResidualBlock(new BinaryCostFunction(), NULL, &x, &y);
-  problem.AddResidualBlock(new UnaryCostFunction(), NULL, &y);
+  problem.AddResidualBlock(new UnaryCostFunction(), nullptr, &x);
+  problem.AddResidualBlock(new BinaryCostFunction(), nullptr, &z, &x);
+  problem.AddResidualBlock(new BinaryCostFunction(), nullptr, &z, &y);
+  problem.AddResidualBlock(new UnaryCostFunction(), nullptr, &z);
+  problem.AddResidualBlock(new BinaryCostFunction(), nullptr, &x, &y);
+  problem.AddResidualBlock(new UnaryCostFunction(), nullptr, &y);
 
   ParameterBlockOrdering* linear_solver_ordering = new ParameterBlockOrdering;
   linear_solver_ordering->AddElementToGroup(&x, 0);
@@ -107,9 +108,7 @@
 
   std::string message;
   EXPECT_TRUE(LexicographicallyOrderResidualBlocks(
-                  2,
-                  problem.mutable_program(),
-                  &message));
+      2, problem.mutable_program(), &message));
   EXPECT_EQ(residual_blocks.size(), expected_residual_blocks.size());
   for (int i = 0; i < expected_residual_blocks.size(); ++i) {
     EXPECT_EQ(residual_blocks[i], expected_residual_blocks[i]);
@@ -132,10 +131,8 @@
 
   Program program(problem.program());
   std::string message;
-  EXPECT_FALSE(ApplyOrdering(problem.parameter_map(),
-                             linear_solver_ordering,
-                             &program,
-                             &message));
+  EXPECT_FALSE(ApplyOrdering(
+      problem.parameter_map(), linear_solver_ordering, &program, &message));
 }
 
 TEST(_, ApplyOrderingNormal) {
@@ -156,10 +153,8 @@
   Program* program = problem.mutable_program();
   std::string message;
 
-  EXPECT_TRUE(ApplyOrdering(problem.parameter_map(),
-                            linear_solver_ordering,
-                            program,
-                            &message));
+  EXPECT_TRUE(ApplyOrdering(
+      problem.parameter_map(), linear_solver_ordering, program, &message));
   const vector<ParameterBlock*>& parameter_blocks = program->parameter_blocks();
 
   EXPECT_EQ(parameter_blocks.size(), 3);
@@ -169,16 +164,16 @@
 }
 
 #ifndef CERES_NO_SUITESPARSE
-class ReorderProgramForSparseNormalCholeskyUsingSuiteSparseTest :
-      public ::testing::Test {
+class ReorderProgramFoSparseCholeskyUsingSuiteSparseTest
+    : public ::testing::Test {
  protected:
   void SetUp() {
-    problem_.AddResidualBlock(new UnaryCostFunction(), NULL, &x_);
-    problem_.AddResidualBlock(new BinaryCostFunction(), NULL, &z_, &x_);
-    problem_.AddResidualBlock(new BinaryCostFunction(), NULL, &z_, &y_);
-    problem_.AddResidualBlock(new UnaryCostFunction(), NULL, &z_);
-    problem_.AddResidualBlock(new BinaryCostFunction(), NULL, &x_, &y_);
-    problem_.AddResidualBlock(new UnaryCostFunction(), NULL, &y_);
+    problem_.AddResidualBlock(new UnaryCostFunction(), nullptr, &x_);
+    problem_.AddResidualBlock(new BinaryCostFunction(), nullptr, &z_, &x_);
+    problem_.AddResidualBlock(new BinaryCostFunction(), nullptr, &z_, &y_);
+    problem_.AddResidualBlock(new UnaryCostFunction(), nullptr, &z_);
+    problem_.AddResidualBlock(new BinaryCostFunction(), nullptr, &x_, &y_);
+    problem_.AddResidualBlock(new UnaryCostFunction(), nullptr, &y_);
   }
 
   void ComputeAndValidateOrdering(
@@ -188,11 +183,11 @@
         program->parameter_blocks();
 
     std::string error;
-    EXPECT_TRUE(ReorderProgramForSparseNormalCholesky(
-                    ceres::SUITE_SPARSE,
-                    linear_solver_ordering,
-                    program,
-                    &error));
+    EXPECT_TRUE(ReorderProgramForSparseCholesky(ceres::SUITE_SPARSE,
+                                                linear_solver_ordering,
+                                                0, /* use all rows */
+                                                program,
+                                                &error));
     const vector<ParameterBlock*>& ordered_parameter_blocks =
         program->parameter_blocks();
     EXPECT_EQ(ordered_parameter_blocks.size(),
@@ -208,7 +203,7 @@
   double z_;
 };
 
-TEST_F(ReorderProgramForSparseNormalCholeskyUsingSuiteSparseTest,
+TEST_F(ReorderProgramFoSparseCholeskyUsingSuiteSparseTest,
        EverythingInGroupZero) {
   ParameterBlockOrdering linear_solver_ordering;
   linear_solver_ordering.AddElementToGroup(&x_, 0);
@@ -218,8 +213,7 @@
   ComputeAndValidateOrdering(linear_solver_ordering);
 }
 
-TEST_F(ReorderProgramForSparseNormalCholeskyUsingSuiteSparseTest,
-       ContiguousGroups) {
+TEST_F(ReorderProgramFoSparseCholeskyUsingSuiteSparseTest, ContiguousGroups) {
   ParameterBlockOrdering linear_solver_ordering;
   linear_solver_ordering.AddElementToGroup(&x_, 0);
   linear_solver_ordering.AddElementToGroup(&y_, 1);
@@ -228,8 +222,7 @@
   ComputeAndValidateOrdering(linear_solver_ordering);
 }
 
-TEST_F(ReorderProgramForSparseNormalCholeskyUsingSuiteSparseTest,
-       GroupsWithGaps) {
+TEST_F(ReorderProgramFoSparseCholeskyUsingSuiteSparseTest, GroupsWithGaps) {
   ParameterBlockOrdering linear_solver_ordering;
   linear_solver_ordering.AddElementToGroup(&x_, 0);
   linear_solver_ordering.AddElementToGroup(&y_, 2);
@@ -238,7 +231,7 @@
   ComputeAndValidateOrdering(linear_solver_ordering);
 }
 
-TEST_F(ReorderProgramForSparseNormalCholeskyUsingSuiteSparseTest,
+TEST_F(ReorderProgramFoSparseCholeskyUsingSuiteSparseTest,
        NonContiguousStartingAtTwo) {
   ParameterBlockOrdering linear_solver_ordering;
   linear_solver_ordering.AddElementToGroup(&x_, 2);
@@ -249,5 +242,45 @@
 }
 #endif  // CERES_NO_SUITESPARSE
 
+TEST(_, ReorderResidualBlocksbyPartition) {
+  ProblemImpl problem;
+  double x;
+  double y;
+  double z;
+
+  problem.AddParameterBlock(&x, 1);
+  problem.AddParameterBlock(&y, 1);
+  problem.AddParameterBlock(&z, 1);
+
+  problem.AddResidualBlock(new UnaryCostFunction(), nullptr, &x);
+  problem.AddResidualBlock(new BinaryCostFunction(), nullptr, &z, &x);
+  problem.AddResidualBlock(new BinaryCostFunction(), nullptr, &z, &y);
+  problem.AddResidualBlock(new UnaryCostFunction(), nullptr, &z);
+  problem.AddResidualBlock(new BinaryCostFunction(), nullptr, &x, &y);
+  problem.AddResidualBlock(new UnaryCostFunction(), nullptr, &y);
+
+  std::vector<ResidualBlockId> residual_block_ids;
+  problem.GetResidualBlocks(&residual_block_ids);
+  std::vector<ResidualBlock*> residual_blocks =
+      problem.program().residual_blocks();
+  auto rng = std::default_random_engine{};
+  for (int i = 1; i < 6; ++i) {
+    std::shuffle(
+        std::begin(residual_block_ids), std::end(residual_block_ids), rng);
+    std::unordered_set<ResidualBlockId> bottom(residual_block_ids.begin(),
+                                               residual_block_ids.begin() + i);
+    const int start_bottom =
+        ReorderResidualBlocksByPartition(bottom, problem.mutable_program());
+    std::vector<ResidualBlock*> actual_residual_blocks =
+        problem.program().residual_blocks();
+    EXPECT_THAT(actual_residual_blocks,
+                testing::UnorderedElementsAreArray(residual_blocks));
+    EXPECT_EQ(start_bottom, residual_blocks.size() - i);
+    for (int j = start_bottom; j < residual_blocks.size(); ++j) {
+      EXPECT_THAT(bottom, ::testing::Contains(actual_residual_blocks[j]));
+    }
+  }
+}
+
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/residual_block.cc b/internal/ceres/residual_block.cc
index 7582e92..067c9ef 100644
--- a/internal/ceres/residual_block.cc
+++ b/internal/ceres/residual_block.cc
@@ -34,14 +34,15 @@
 #include <algorithm>
 #include <cstddef>
 #include <vector>
+
 #include "ceres/corrector.h"
-#include "ceres/parameter_block.h"
-#include "ceres/residual_block_utils.h"
 #include "ceres/cost_function.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/fixed_array.h"
 #include "ceres/local_parameterization.h"
 #include "ceres/loss_function.h"
+#include "ceres/parameter_block.h"
+#include "ceres/residual_block_utils.h"
 #include "ceres/small_blas.h"
 
 using Eigen::Dynamic;
@@ -50,8 +51,10 @@
 namespace internal {
 
 ResidualBlock::ResidualBlock(
-    const CostFunction* cost_function, const LossFunction* loss_function,
-    const std::vector<ParameterBlock*>& parameter_blocks, int index)
+    const CostFunction* cost_function,
+    const LossFunction* loss_function,
+    const std::vector<ParameterBlock*>& parameter_blocks,
+    int index)
     : cost_function_(cost_function),
       loss_function_(loss_function),
       parameter_blocks_(
@@ -80,11 +83,11 @@
 
   // Put pointers into the scratch space into global_jacobians as appropriate.
   FixedArray<double*, 8> global_jacobians(num_parameter_blocks);
-  if (jacobians != NULL) {
+  if (jacobians != nullptr) {
     for (int i = 0; i < num_parameter_blocks; ++i) {
       const ParameterBlock* parameter_block = parameter_blocks_[i];
-      if (jacobians[i] != NULL &&
-          parameter_block->LocalParameterizationJacobian() != NULL) {
+      if (jacobians[i] != nullptr &&
+          parameter_block->LocalParameterizationJacobian() != nullptr) {
         global_jacobians[i] = scratch;
         scratch += num_residuals * parameter_block->Size();
       } else {
@@ -94,7 +97,7 @@
   }
 
   // If the caller didn't request residuals, use the scratch space for them.
-  bool outputting_residuals = (residuals != NULL);
+  bool outputting_residuals = (residuals != nullptr);
   if (!outputting_residuals) {
     residuals = scratch;
   }
@@ -102,30 +105,27 @@
   // Invalidate the evaluation buffers so that we can check them after
   // the CostFunction::Evaluate call, to see if all the return values
   // that were required were written to and that they are finite.
-  double** eval_jacobians = (jacobians != NULL) ? global_jacobians.get() : NULL;
+  double** eval_jacobians =
+      (jacobians != nullptr) ? global_jacobians.data() : nullptr;
 
   InvalidateEvaluation(*this, cost, residuals, eval_jacobians);
 
-  if (!cost_function_->Evaluate(parameters.get(), residuals, eval_jacobians)) {
+  if (!cost_function_->Evaluate(parameters.data(), residuals, eval_jacobians)) {
     return false;
   }
 
-  if (!IsEvaluationValid(*this,
-                         parameters.get(),
-                         cost,
-                         residuals,
-                         eval_jacobians)) {
+  if (!IsEvaluationValid(
+          *this, parameters.data(), cost, residuals, eval_jacobians)) {
+    // clang-format off
     std::string message =
         "\n\n"
         "Error in evaluating the ResidualBlock.\n\n"
         "There are two possible reasons. Either the CostFunction did not evaluate and fill all    \n"  // NOLINT
         "residual and jacobians that were requested or there was a non-finite value (nan/infinite)\n"  // NOLINT
         "generated during the or jacobian computation. \n\n" +
-        EvaluationToString(*this,
-                           parameters.get(),
-                           cost,
-                           residuals,
-                           eval_jacobians);
+        EvaluationToString(
+            *this, parameters.data(), cost, residuals, eval_jacobians);
+    // clang-format on
     LOG(WARNING) << message;
     return false;
   }
@@ -133,13 +133,13 @@
   double squared_norm = VectorRef(residuals, num_residuals).squaredNorm();
 
   // Update the jacobians with the local parameterizations.
-  if (jacobians != NULL) {
+  if (jacobians != nullptr) {
     for (int i = 0; i < num_parameter_blocks; ++i) {
-      if (jacobians[i] != NULL) {
+      if (jacobians[i] != nullptr) {
         const ParameterBlock* parameter_block = parameter_blocks_[i];
 
         // Apply local reparameterization to the jacobians.
-        if (parameter_block->LocalParameterizationJacobian() != NULL) {
+        if (parameter_block->LocalParameterizationJacobian() != nullptr) {
           // jacobians[i] = global_jacobians[i] * global_to_local_jacobian.
           MatrixMatrixMultiply<Dynamic, Dynamic, Dynamic, Dynamic, 0>(
               global_jacobians[i],
@@ -148,13 +148,17 @@
               parameter_block->LocalParameterizationJacobian(),
               parameter_block->Size(),
               parameter_block->LocalSize(),
-              jacobians[i], 0, 0,  num_residuals, parameter_block->LocalSize());
+              jacobians[i],
+              0,
+              0,
+              num_residuals,
+              parameter_block->LocalSize());
         }
       }
     }
   }
 
-  if (loss_function_ == NULL || !apply_loss_function) {
+  if (loss_function_ == nullptr || !apply_loss_function) {
     *cost = 0.5 * squared_norm;
     return true;
   }
@@ -165,16 +169,16 @@
 
   // No jacobians and not outputting residuals? All done. Doing an early exit
   // here avoids constructing the "Corrector" object below in a common case.
-  if (jacobians == NULL && !outputting_residuals) {
+  if (jacobians == nullptr && !outputting_residuals) {
     return true;
   }
 
   // Correct for the effects of the loss function. The jacobians need to be
   // corrected before the residuals, since they use the uncorrected residuals.
   Corrector correct(squared_norm, rho);
-  if (jacobians != NULL) {
+  if (jacobians != nullptr) {
     for (int i = 0; i < num_parameter_blocks; ++i) {
-      if (jacobians[i] != NULL) {
+      if (jacobians[i] != nullptr) {
         const ParameterBlock* parameter_block = parameter_blocks_[i];
 
         // Correct the jacobians for the loss function.
@@ -204,8 +208,7 @@
   int scratch_doubles = 1;
   for (int i = 0; i < num_parameters; ++i) {
     const ParameterBlock* parameter_block = parameter_blocks_[i];
-    if (!parameter_block->IsConstant() &&
-        parameter_block->LocalParameterizationJacobian() != NULL) {
+    if (parameter_block->LocalParameterizationJacobian() != nullptr) {
       scratch_doubles += parameter_block->Size();
     }
   }
diff --git a/internal/ceres/residual_block.h b/internal/ceres/residual_block.h
index 6964c6d..f28fd42 100644
--- a/internal/ceres/residual_block.h
+++ b/internal/ceres/residual_block.h
@@ -65,7 +65,7 @@
 //
 // The residual block stores pointers to but does not own the cost functions,
 // loss functions, and parameter blocks.
-class ResidualBlock {
+class CERES_EXPORT_INTERNAL ResidualBlock {
  public:
   // Construct the residual block with the given cost/loss functions. Loss may
   // be null. The index is the index of the residual block in the Program's
@@ -82,6 +82,8 @@
   // computed. If jacobians[i] is NULL, then the jacobian for that parameter is
   // not computed.
   //
+  // cost must not be null.
+  //
   // Evaluate needs scratch space which must be supplied by the caller via
   // scratch. The array should have at least NumScratchDoublesForEvaluate()
   // space available.
@@ -103,7 +105,6 @@
                 double** jacobians,
                 double* scratch) const;
 
-
   const CostFunction* cost_function() const { return cost_function_; }
   const LossFunction* loss_function() const { return loss_function_; }
 
diff --git a/internal/ceres/residual_block_test.cc b/internal/ceres/residual_block_test.cc
index 3a33be7..3c05f48 100644
--- a/internal/ceres/residual_block_test.cc
+++ b/internal/ceres/residual_block_test.cc
@@ -31,11 +31,12 @@
 #include "ceres/residual_block.h"
 
 #include <cstdint>
-#include "gtest/gtest.h"
-#include "ceres/parameter_block.h"
-#include "ceres/sized_cost_function.h"
+
 #include "ceres/internal/eigen.h"
 #include "ceres/local_parameterization.h"
+#include "ceres/parameter_block.h"
+#include "ceres/sized_cost_function.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
@@ -43,7 +44,7 @@
 using std::vector;
 
 // Trivial cost function that accepts three arguments.
-class TernaryCostFunction: public CostFunction {
+class TernaryCostFunction : public CostFunction {
  public:
   TernaryCostFunction(int num_residuals,
                       int32_t parameter_block1_size,
@@ -55,18 +56,17 @@
     mutable_parameter_block_sizes()->push_back(parameter_block3_size);
   }
 
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     for (int i = 0; i < num_residuals(); ++i) {
       residuals[i] = i;
     }
     if (jacobians) {
       for (int k = 0; k < 3; ++k) {
         if (jacobians[k] != NULL) {
-          MatrixRef jacobian(jacobians[k],
-                             num_residuals(),
-                             parameter_block_sizes()[k]);
+          MatrixRef jacobian(
+              jacobians[k], num_residuals(), parameter_block_sizes()[k]);
           jacobian.setConstant(k);
         }
       }
@@ -109,12 +109,12 @@
   // Verify cost-only evaluation.
   double cost;
   residual_block.Evaluate(true, &cost, NULL, NULL, scratch);
-  EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
+  EXPECT_EQ(0.5 * (0 * 0 + 1 * 1 + 2 * 2), cost);
 
   // Verify cost and residual evaluation.
   double residuals[3];
   residual_block.Evaluate(true, &cost, residuals, NULL, scratch);
-  EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
+  EXPECT_EQ(0.5 * (0 * 0 + 1 * 1 + 2 * 2), cost);
   EXPECT_EQ(0.0, residuals[0]);
   EXPECT_EQ(1.0, residuals[1]);
   EXPECT_EQ(2.0, residuals[2]);
@@ -131,14 +131,11 @@
   jacobian_ry.setConstant(-1.0);
   jacobian_rz.setConstant(-1.0);
 
-  double *jacobian_ptrs[3] = {
-    jacobian_rx.data(),
-    jacobian_ry.data(),
-    jacobian_rz.data()
-  };
+  double* jacobian_ptrs[3] = {
+      jacobian_rx.data(), jacobian_ry.data(), jacobian_rz.data()};
 
   residual_block.Evaluate(true, &cost, residuals, jacobian_ptrs, scratch);
-  EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
+  EXPECT_EQ(0.5 * (0 * 0 + 1 * 1 + 2 * 2), cost);
   EXPECT_EQ(0.0, residuals[0]);
   EXPECT_EQ(1.0, residuals[1]);
   EXPECT_EQ(2.0, residuals[2]);
@@ -157,22 +154,24 @@
   jacobian_ptrs[1] = NULL;  // Don't compute the jacobian for y.
 
   residual_block.Evaluate(true, &cost, residuals, jacobian_ptrs, scratch);
-  EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
+  EXPECT_EQ(0.5 * (0 * 0 + 1 * 1 + 2 * 2), cost);
   EXPECT_EQ(0.0, residuals[0]);
   EXPECT_EQ(1.0, residuals[1]);
   EXPECT_EQ(2.0, residuals[2]);
 
+  // clang-format off
   EXPECT_TRUE((jacobian_rx.array() ==  0.0).all()) << "\n" << jacobian_rx;
   EXPECT_TRUE((jacobian_ry.array() == -1.0).all()) << "\n" << jacobian_ry;
   EXPECT_TRUE((jacobian_rz.array() ==  2.0).all()) << "\n" << jacobian_rz;
+  // clang-format on
 }
 
 // Trivial cost function that accepts three arguments.
-class LocallyParameterizedCostFunction: public SizedCostFunction<3, 2, 3, 4> {
+class LocallyParameterizedCostFunction : public SizedCostFunction<3, 2, 3, 4> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     for (int i = 0; i < num_residuals(); ++i) {
       residuals[i] = i;
     }
@@ -189,9 +188,8 @@
         //   0 1 2 3 4 ...
         //
         if (jacobians[k] != NULL) {
-          MatrixRef jacobian(jacobians[k],
-                             num_residuals(),
-                             parameter_block_sizes()[k]);
+          MatrixRef jacobian(
+              jacobians[k], num_residuals(), parameter_block_sizes()[k]);
           for (int j = 0; j < k + 2; ++j) {
             jacobian.col(j).setConstant(j);
           }
@@ -243,17 +241,17 @@
   EXPECT_EQ(parameters[0], residual_block.parameter_blocks()[0]);
   EXPECT_EQ(parameters[1], residual_block.parameter_blocks()[1]);
   EXPECT_EQ(parameters[2], residual_block.parameter_blocks()[2]);
-  EXPECT_EQ(3*(2 + 4) + 3, residual_block.NumScratchDoublesForEvaluate());
+  EXPECT_EQ(3 * (2 + 4) + 3, residual_block.NumScratchDoublesForEvaluate());
 
   // Verify cost-only evaluation.
   double cost;
   residual_block.Evaluate(true, &cost, NULL, NULL, scratch);
-  EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
+  EXPECT_EQ(0.5 * (0 * 0 + 1 * 1 + 2 * 2), cost);
 
   // Verify cost and residual evaluation.
   double residuals[3];
   residual_block.Evaluate(true, &cost, residuals, NULL, scratch);
-  EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
+  EXPECT_EQ(0.5 * (0 * 0 + 1 * 1 + 2 * 2), cost);
   EXPECT_EQ(0.0, residuals[0]);
   EXPECT_EQ(1.0, residuals[1]);
   EXPECT_EQ(2.0, residuals[2]);
@@ -270,18 +268,17 @@
   jacobian_ry.setConstant(-1.0);
   jacobian_rz.setConstant(-1.0);
 
-  double *jacobian_ptrs[3] = {
-    jacobian_rx.data(),
-    jacobian_ry.data(),
-    jacobian_rz.data()
-  };
+  double* jacobian_ptrs[3] = {
+      jacobian_rx.data(), jacobian_ry.data(), jacobian_rz.data()};
 
   residual_block.Evaluate(true, &cost, residuals, jacobian_ptrs, scratch);
-  EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
+  EXPECT_EQ(0.5 * (0 * 0 + 1 * 1 + 2 * 2), cost);
   EXPECT_EQ(0.0, residuals[0]);
   EXPECT_EQ(1.0, residuals[1]);
   EXPECT_EQ(2.0, residuals[2]);
 
+  // clang-format off
+
   Matrix expected_jacobian_rx(3, 1);
   expected_jacobian_rx << 1.0, 1.0, 1.0;
 
@@ -305,6 +302,8 @@
       << "\nExpected:\n " << expected_jacobian_rz
       << "\nActual:\n"   << jacobian_rz;
 
+  // clang-format on
+
   // Verify cost, residual, and partial jacobian evaluation.
   cost = 0.0;
   VectorRef(residuals, 3).setConstant(0.0);
@@ -315,7 +314,7 @@
   jacobian_ptrs[1] = NULL;  // Don't compute the jacobian for y.
 
   residual_block.Evaluate(true, &cost, residuals, jacobian_ptrs, scratch);
-  EXPECT_EQ(0.5 * (0*0 + 1*1 + 2*2), cost);
+  EXPECT_EQ(0.5 * (0 * 0 + 1 * 1 + 2 * 2), cost);
   EXPECT_EQ(0.0, residuals[0]);
   EXPECT_EQ(1.0, residuals[1]);
   EXPECT_EQ(2.0, residuals[2]);
diff --git a/internal/ceres/residual_block_utils.cc b/internal/ceres/residual_block_utils.cc
index 35e928b..d5b3fa1 100644
--- a/internal/ceres/residual_block_utils.cc
+++ b/internal/ceres/residual_block_utils.cc
@@ -33,6 +33,7 @@
 #include <cmath>
 #include <cstddef>
 #include <limits>
+
 #include "ceres/array_utils.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/internal/port.h"
@@ -75,6 +76,7 @@
   const int num_residuals = block.NumResiduals();
   string result = "";
 
+  // clang-format off
   StringAppendF(&result,
                 "Residual Block size: %d parameter blocks x %d residuals\n\n",
                 num_parameter_blocks, num_residuals);
@@ -85,6 +87,7 @@
       "of the Jacobian/residual array was requested but was not written to by user code, it is \n"  // NOLINT
       "indicated by 'Uninitialized'. This is an error. Residuals or Jacobian values evaluating \n"  // NOLINT
       "to Inf or NaN is also an error.  \n\n"; // NOLINT
+  // clang-format on
 
   string space = "Residuals:     ";
   result += space;
@@ -102,8 +105,8 @@
       for (int k = 0; k < num_residuals; ++k) {
         AppendArrayToString(1,
                             (jacobians != NULL && jacobians[i] != NULL)
-                            ? jacobians[i] + k * parameter_block_size + j
-                            : NULL,
+                                ? jacobians[i] + k * parameter_block_size + j
+                                : NULL,
                             &result);
       }
       StringAppendF(&result, "\n");
diff --git a/internal/ceres/residual_block_utils.h b/internal/ceres/residual_block_utils.h
index 627337f..41ae81a 100644
--- a/internal/ceres/residual_block_utils.h
+++ b/internal/ceres/residual_block_utils.h
@@ -44,6 +44,7 @@
 #define CERES_INTERNAL_RESIDUAL_BLOCK_UTILS_H_
 
 #include <string>
+
 #include "ceres/internal/port.h"
 
 namespace ceres {
diff --git a/internal/ceres/residual_block_utils_test.cc b/internal/ceres/residual_block_utils_test.cc
index 3beaa10..331f5ab 100644
--- a/internal/ceres/residual_block_utils_test.cc
+++ b/internal/ceres/residual_block_utils_test.cc
@@ -28,31 +28,30 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/residual_block_utils.h"
+
 #include <cmath>
 #include <limits>
 #include <memory>
-#include "gtest/gtest.h"
+
+#include "ceres/cost_function.h"
 #include "ceres/parameter_block.h"
 #include "ceres/residual_block.h"
-#include "ceres/residual_block_utils.h"
-#include "ceres/cost_function.h"
 #include "ceres/sized_cost_function.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
 
 // Routine to check if ResidualBlock::Evaluate for unary CostFunction
 // with one residual succeeds with true or dies.
-void CheckEvaluation(const CostFunction& cost_function, bool is_good) {
+static void CheckEvaluation(const CostFunction& cost_function, bool is_good) {
   double x = 1.0;
   ParameterBlock parameter_block(&x, 1, -1);
   std::vector<ParameterBlock*> parameter_blocks;
   parameter_blocks.push_back(&parameter_block);
 
-  ResidualBlock residual_block(&cost_function,
-                               NULL,
-                               parameter_blocks,
-                               -1);
+  ResidualBlock residual_block(&cost_function, NULL, parameter_blocks, -1);
 
   std::unique_ptr<double[]> scratch(
       new double[residual_block.NumScratchDoublesForEvaluate()]);
@@ -60,22 +59,20 @@
   double cost;
   double residuals;
   double jacobian;
-  double* jacobians[] = { &jacobian };
+  double* jacobians[] = {&jacobian};
 
-  EXPECT_EQ(residual_block.Evaluate(true,
-                                    &cost,
-                                    &residuals,
-                                    jacobians,
-                                    scratch.get()), is_good);
+  EXPECT_EQ(residual_block.Evaluate(
+                true, &cost, &residuals, jacobians, scratch.get()),
+            is_good);
 }
 
 // A CostFunction that behaves normaly, i.e., it computes numerically
 // valid residuals and jacobians.
-class GoodCostFunction: public SizedCostFunction<1, 1> {
+class GoodCostFunction : public SizedCostFunction<1, 1> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     residuals[0] = 1;
     if (jacobians != NULL && jacobians[0] != NULL) {
       jacobians[0][0] = 0.0;
@@ -86,11 +83,11 @@
 
 // The following four CostFunctions simulate the different ways in
 // which user code can cause ResidualBlock::Evaluate to fail.
-class NoResidualUpdateCostFunction: public SizedCostFunction<1, 1> {
+class NoResidualUpdateCostFunction : public SizedCostFunction<1, 1> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     // Forget to update the residuals.
     // residuals[0] = 1;
     if (jacobians != NULL && jacobians[0] != NULL) {
@@ -100,11 +97,11 @@
   }
 };
 
-class NoJacobianUpdateCostFunction: public SizedCostFunction<1, 1> {
+class NoJacobianUpdateCostFunction : public SizedCostFunction<1, 1> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     residuals[0] = 1;
     if (jacobians != NULL && jacobians[0] != NULL) {
       // Forget to update the jacobians.
@@ -114,11 +111,11 @@
   }
 };
 
-class BadResidualCostFunction: public SizedCostFunction<1, 1> {
+class BadResidualCostFunction : public SizedCostFunction<1, 1> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     residuals[0] = std::numeric_limits<double>::infinity();
     if (jacobians != NULL && jacobians[0] != NULL) {
       jacobians[0][0] = 0.0;
@@ -127,11 +124,11 @@
   }
 };
 
-class BadJacobianCostFunction: public SizedCostFunction<1, 1> {
+class BadJacobianCostFunction : public SizedCostFunction<1, 1> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     residuals[0] = 1.0;
     if (jacobians != NULL && jacobians[0] != NULL) {
       jacobians[0][0] = std::numeric_limits<double>::quiet_NaN();
diff --git a/internal/ceres/rotation_test.cc b/internal/ceres/rotation_test.cc
index d980ba2..fc39b31 100644
--- a/internal/ceres/rotation_test.cc
+++ b/internal/ceres/rotation_test.cc
@@ -28,14 +28,16 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/rotation.h"
+
 #include <cmath>
 #include <limits>
 #include <string>
+
 #include "ceres/internal/eigen.h"
-#include "ceres/is_close.h"
 #include "ceres/internal/port.h"
+#include "ceres/is_close.h"
 #include "ceres/jet.h"
-#include "ceres/rotation.h"
 #include "ceres/stringprintf.h"
 #include "ceres/test_util.h"
 #include "glog/logging.h"
@@ -45,8 +47,8 @@
 namespace ceres {
 namespace internal {
 
-using std::min;
 using std::max;
+using std::min;
 using std::numeric_limits;
 using std::string;
 using std::swap;
@@ -54,7 +56,7 @@
 const double kPi = 3.14159265358979323846;
 const double kHalfSqrt2 = 0.707106781186547524401;
 
-double RandDouble() {
+static double RandDouble() {
   double r = rand();
   return r / RAND_MAX;
 }
@@ -74,8 +76,8 @@
     return false;
   }
 
-  double norm2 = arg[0] * arg[0] + arg[1] * arg[1] +
-      arg[2] * arg[2] + arg[3] * arg[3];
+  double norm2 =
+      arg[0] * arg[0] + arg[1] * arg[1] + arg[2] * arg[2] + arg[3] * arg[3];
   if (fabs(norm2 - 1.0) > kTolerance) {
     *result_listener << "squared norm is " << norm2;
     return false;
@@ -120,6 +122,7 @@
     return true;
   }
 
+  // clang-format off
   *result_listener << "expected : "
                    << expected[0] << " "
                    << expected[1] << " "
@@ -130,6 +133,7 @@
                    << arg[1] << " "
                    << arg[2] << " "
                    << arg[3];
+  // clang-format on
   return false;
 }
 
@@ -164,6 +168,7 @@
     return true;
   }
 
+  // clang-format off
   *result_listener << " arg:"
                    << " " << arg[0]
                    << " " << arg[1]
@@ -172,6 +177,7 @@
                    << " " << expected[0]
                    << " " << expected[1]
                    << " " << expected[2];
+  // clang-format on
   return false;
 }
 
@@ -225,9 +231,9 @@
 
 // Transforms a zero axis/angle to a quaternion.
 TEST(Rotation, ZeroAngleAxisToQuaternion) {
-  double axis_angle[3] = { 0, 0, 0 };
+  double axis_angle[3] = {0, 0, 0};
   double quaternion[4];
-  double expected[4] = { 1, 0, 0, 0 };
+  double expected[4] = {1, 0, 0, 0};
   AngleAxisToQuaternion(axis_angle, quaternion);
   EXPECT_THAT(quaternion, IsNormalizedQuaternion());
   EXPECT_THAT(quaternion, IsNearQuaternion(expected));
@@ -237,9 +243,9 @@
 TEST(Rotation, SmallAngleAxisToQuaternion) {
   // Small, finite value to test.
   double theta = 1.0e-2;
-  double axis_angle[3] = { theta, 0, 0 };
+  double axis_angle[3] = {theta, 0, 0};
   double quaternion[4];
-  double expected[4] = { cos(theta/2), sin(theta/2.0), 0, 0 };
+  double expected[4] = {cos(theta / 2), sin(theta / 2.0), 0, 0};
   AngleAxisToQuaternion(axis_angle, quaternion);
   EXPECT_THAT(quaternion, IsNormalizedQuaternion());
   EXPECT_THAT(quaternion, IsNearQuaternion(expected));
@@ -249,9 +255,9 @@
 TEST(Rotation, TinyAngleAxisToQuaternion) {
   // Very small value that could potentially cause underflow.
   double theta = pow(numeric_limits<double>::min(), 0.75);
-  double axis_angle[3] = { theta, 0, 0 };
+  double axis_angle[3] = {theta, 0, 0};
   double quaternion[4];
-  double expected[4] = { cos(theta/2), sin(theta/2.0), 0, 0 };
+  double expected[4] = {cos(theta / 2), sin(theta / 2.0), 0, 0};
   AngleAxisToQuaternion(axis_angle, quaternion);
   EXPECT_THAT(quaternion, IsNormalizedQuaternion());
   EXPECT_THAT(quaternion, IsNearQuaternion(expected));
@@ -259,9 +265,9 @@
 
 // Transforms a rotation by pi/2 around X to a quaternion.
 TEST(Rotation, XRotationToQuaternion) {
-  double axis_angle[3] = { kPi / 2, 0, 0 };
+  double axis_angle[3] = {kPi / 2, 0, 0};
   double quaternion[4];
-  double expected[4] = { kHalfSqrt2, kHalfSqrt2, 0, 0 };
+  double expected[4] = {kHalfSqrt2, kHalfSqrt2, 0, 0};
   AngleAxisToQuaternion(axis_angle, quaternion);
   EXPECT_THAT(quaternion, IsNormalizedQuaternion());
   EXPECT_THAT(quaternion, IsNearQuaternion(expected));
@@ -269,18 +275,18 @@
 
 // Transforms a unit quaternion to an axis angle.
 TEST(Rotation, UnitQuaternionToAngleAxis) {
-  double quaternion[4] = { 1, 0, 0, 0 };
+  double quaternion[4] = {1, 0, 0, 0};
   double axis_angle[3];
-  double expected[3] = { 0, 0, 0 };
+  double expected[3] = {0, 0, 0};
   QuaternionToAngleAxis(quaternion, axis_angle);
   EXPECT_THAT(axis_angle, IsNearAngleAxis(expected));
 }
 
 // Transforms a quaternion that rotates by pi about the Y axis to an axis angle.
 TEST(Rotation, YRotationQuaternionToAngleAxis) {
-  double quaternion[4] = { 0, 0, 1, 0 };
+  double quaternion[4] = {0, 0, 1, 0};
   double axis_angle[3];
-  double expected[3] = { 0, kPi, 0 };
+  double expected[3] = {0, kPi, 0};
   QuaternionToAngleAxis(quaternion, axis_angle);
   EXPECT_THAT(axis_angle, IsNearAngleAxis(expected));
 }
@@ -288,9 +294,9 @@
 // Transforms a quaternion that rotates by pi/3 about the Z axis to an axis
 // angle.
 TEST(Rotation, ZRotationQuaternionToAngleAxis) {
-  double quaternion[4] = { sqrt(3) / 2, 0, 0, 0.5 };
+  double quaternion[4] = {sqrt(3) / 2, 0, 0, 0.5};
   double axis_angle[3];
-  double expected[3] = { 0, 0, kPi / 3 };
+  double expected[3] = {0, 0, kPi / 3};
   QuaternionToAngleAxis(quaternion, axis_angle);
   EXPECT_THAT(axis_angle, IsNearAngleAxis(expected));
 }
@@ -299,9 +305,9 @@
 TEST(Rotation, SmallQuaternionToAngleAxis) {
   // Small, finite value to test.
   double theta = 1.0e-2;
-  double quaternion[4] = { cos(theta/2), sin(theta/2.0), 0, 0 };
+  double quaternion[4] = {cos(theta / 2), sin(theta / 2.0), 0, 0};
   double axis_angle[3];
-  double expected[3] = { theta, 0, 0 };
+  double expected[3] = {theta, 0, 0};
   QuaternionToAngleAxis(quaternion, axis_angle);
   EXPECT_THAT(axis_angle, IsNearAngleAxis(expected));
 }
@@ -310,9 +316,9 @@
 TEST(Rotation, TinyQuaternionToAngleAxis) {
   // Very small value that could potentially cause underflow.
   double theta = pow(numeric_limits<double>::min(), 0.75);
-  double quaternion[4] = { cos(theta/2), sin(theta/2.0), 0, 0 };
+  double quaternion[4] = {cos(theta / 2), sin(theta / 2.0), 0, 0};
   double axis_angle[3];
-  double expected[3] = { theta, 0, 0 };
+  double expected[3] = {theta, 0, 0};
   QuaternionToAngleAxis(quaternion, axis_angle);
   EXPECT_THAT(axis_angle, IsNearAngleAxis(expected));
 }
@@ -328,13 +334,13 @@
   quaternion[2] = 0.0;
   quaternion[3] = 0.0;
   QuaternionToAngleAxis(quaternion, angle_axis);
-  const double angle = sqrt(angle_axis[0] * angle_axis[0] +
-                            angle_axis[1] * angle_axis[1] +
-                            angle_axis[2] * angle_axis[2]);
+  const double angle =
+      sqrt(angle_axis[0] * angle_axis[0] + angle_axis[1] * angle_axis[1] +
+           angle_axis[2] * angle_axis[2]);
   EXPECT_LE(angle, kPi);
 }
 
-static const int kNumTrials = 10000;
+static constexpr int kNumTrials = 10000;
 
 // Takes a bunch of random axis/angle values, converts them to quaternions,
 // and back again.
@@ -398,18 +404,18 @@
 
 // Transforms a zero axis/angle to a rotation matrix.
 TEST(Rotation, ZeroAngleAxisToRotationMatrix) {
-  double axis_angle[3] = { 0, 0, 0 };
+  double axis_angle[3] = {0, 0, 0};
   double matrix[9];
-  double expected[9] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
+  double expected[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
   AngleAxisToRotationMatrix(axis_angle, matrix);
   EXPECT_THAT(matrix, IsOrthonormal());
   EXPECT_THAT(matrix, IsNear3x3Matrix(expected));
 }
 
 TEST(Rotation, NearZeroAngleAxisToRotationMatrix) {
-  double axis_angle[3] = { 1e-24, 2e-24, 3e-24 };
+  double axis_angle[3] = {1e-24, 2e-24, 3e-24};
   double matrix[9];
-  double expected[9] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
+  double expected[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
   AngleAxisToRotationMatrix(axis_angle, matrix);
   EXPECT_THAT(matrix, IsOrthonormal());
   EXPECT_THAT(matrix, IsNear3x3Matrix(expected));
@@ -417,10 +423,10 @@
 
 // Transforms a rotation by pi/2 around X to a rotation matrix and back.
 TEST(Rotation, XRotationToRotationMatrix) {
-  double axis_angle[3] = { kPi / 2, 0, 0 };
+  double axis_angle[3] = {kPi / 2, 0, 0};
   double matrix[9];
   // The rotation matrices are stored column-major.
-  double expected[9] = { 1, 0, 0, 0, 0, 1, 0, -1, 0 };
+  double expected[9] = {1, 0, 0, 0, 0, 1, 0, -1, 0};
   AngleAxisToRotationMatrix(axis_angle, matrix);
   EXPECT_THAT(matrix, IsOrthonormal());
   EXPECT_THAT(matrix, IsNear3x3Matrix(expected));
@@ -432,9 +438,9 @@
 // Transforms an axis angle that rotates by pi about the Y axis to a
 // rotation matrix and back.
 TEST(Rotation, YRotationToRotationMatrix) {
-  double axis_angle[3] = { 0, kPi, 0 };
+  double axis_angle[3] = {0, kPi, 0};
   double matrix[9];
-  double expected[9] = { -1, 0, 0, 0, 1, 0, 0, 0, -1 };
+  double expected[9] = {-1, 0, 0, 0, 1, 0, 0, 0, -1};
   AngleAxisToRotationMatrix(axis_angle, matrix);
   EXPECT_THAT(matrix, IsOrthonormal());
   EXPECT_THAT(matrix, IsNear3x3Matrix(expected));
@@ -475,29 +481,31 @@
 
 TEST(Rotation, AtPiAngleAxisRoundTrip) {
   // A rotation of kPi about the X axis;
-  static const double kMatrix[3][3] = {
+  // clang-format off
+  static constexpr double kMatrix[3][3] = {
     {1.0,  0.0,  0.0},
     {0.0,  -1.0,  0.0},
     {0.0,  0.0,  -1.0}
   };
+  // clang-format on
 
   double in_matrix[9];
   // Fill it from kMatrix in col-major order.
   for (int j = 0, k = 0; j < 3; ++j) {
-     for (int i = 0; i < 3; ++i, ++k) {
-       in_matrix[k] = kMatrix[i][j];
-     }
+    for (int i = 0; i < 3; ++i, ++k) {
+      in_matrix[k] = kMatrix[i][j];
+    }
   }
 
-  const double expected_axis_angle[3] = { kPi, 0, 0 };
+  const double expected_axis_angle[3] = {kPi, 0, 0};
 
   double out_matrix[9];
   double axis_angle[3];
   RotationMatrixToAngleAxis(in_matrix, axis_angle);
   AngleAxisToRotationMatrix(axis_angle, out_matrix);
 
-  LOG(INFO) << "AngleAxis = " << axis_angle[0] << " " << axis_angle[1]
-            << " " << axis_angle[2];
+  LOG(INFO) << "AngleAxis = " << axis_angle[0] << " " << axis_angle[1] << " "
+            << axis_angle[2];
   LOG(INFO) << "Expected AngleAxis = " << kPi << " 0 0";
   double out_rowmajor[3][3];
   for (int j = 0, k = 0; j < 3; ++j) {
@@ -526,13 +534,15 @@
 // Transforms an axis angle that rotates by pi/3 about the Z axis to a
 // rotation matrix.
 TEST(Rotation, ZRotationToRotationMatrix) {
-  double axis_angle[3] =  { 0, 0, kPi / 3 };
+  double axis_angle[3] = {0, 0, kPi / 3};
   double matrix[9];
   // This is laid-out row-major on the screen but is actually stored
   // column-major.
+  // clang-format off
   double expected[9] = { 0.5, sqrt(3) / 2, 0,   // Column 1
                          -sqrt(3) / 2, 0.5, 0,  // Column 2
                          0, 0, 1 };             // Column 3
+  // clang-format on
   AngleAxisToRotationMatrix(axis_angle, matrix);
   EXPECT_THAT(matrix, IsOrthonormal());
   EXPECT_THAT(matrix, IsNear3x3Matrix(expected));
@@ -602,13 +612,12 @@
     RotationMatrixToAngleAxis(matrix, round_trip);
 
     for (int i = 0; i < 3; ++i) {
-      EXPECT_NEAR(round_trip[i], axis_angle[i],
-                  numeric_limits<double>::epsilon());
+      EXPECT_NEAR(
+          round_trip[i], axis_angle[i], numeric_limits<double>::epsilon());
     }
   }
 }
 
-
 // Transposes a 3x3 matrix.
 static void Transpose3x3(double m[9]) {
   swap(m[1], m[3]);
@@ -647,8 +656,7 @@
   for (double x = -1.0; x <= 1.0; x += 1.0) {
     for (double y = -1.0; y <= 1.0; y += 1.0) {
       for (double z = -1.0; z <= 1.0; z += 1.0) {
-        if ((x != 0) + (y != 0) + (z != 0) > 1)
-          continue;
+        if ((x != 0) + (y != 0) + (z != 0) > 1) continue;
         double axis_angle[3] = {x, y, z};
         double euler_angles[3] = {x, y, z};
         CompareEulerToAngleAxis(axis_angle, euler_angles);
@@ -680,6 +688,8 @@
 typedef Jet<double, 3> J3;
 typedef Jet<double, 4> J4;
 
+namespace {
+
 J3 MakeJ3(double a, double v0, double v1, double v2) {
   J3 j;
   j.a = a;
@@ -705,8 +715,10 @@
   return internal::IsClose(x, y, kTolerance, NULL, NULL);
 }
 
+}  // namespace
+
 template <int N>
-bool IsClose(const Jet<double, N> &x, const Jet<double, N> &y) {
+bool IsClose(const Jet<double, N>& x, const Jet<double, N>& y) {
   if (!IsClose(x.a, y.a)) {
     return false;
   }
@@ -719,7 +731,7 @@
 }
 
 template <int M, int N>
-void ExpectJetArraysClose(const Jet<double, N> *x, const Jet<double, N> *y) {
+void ExpectJetArraysClose(const Jet<double, N>* x, const Jet<double, N>* y) {
   for (int i = 0; i < M; i++) {
     if (!IsClose(x[i], y[i])) {
       LOG(ERROR) << "Jet " << i << "/" << M << " not equal";
@@ -738,11 +750,11 @@
 
 // Log-10 of a value well below machine precision.
 static const int kSmallTinyCutoff =
-    static_cast<int>(2 * log(numeric_limits<double>::epsilon())/log(10.0));
+    static_cast<int>(2 * log(numeric_limits<double>::epsilon()) / log(10.0));
 
 // Log-10 of a value just below values representable by double.
-static const int kTinyZeroLimit   =
-    static_cast<int>(1 + log(numeric_limits<double>::min())/log(10.0));
+static const int kTinyZeroLimit =
+    static_cast<int>(1 + log(numeric_limits<double>::min()) / log(10.0));
 
 // Test that exact conversion works for small angles when jets are used.
 TEST(Rotation, SmallAngleAxisToQuaternionForJets) {
@@ -750,27 +762,26 @@
   // to be well within the range represented by doubles.
   for (int i = -2; i >= kSmallTinyCutoff; i--) {
     double theta = pow(10.0, i);
-    J3 axis_angle[3] = { J3(theta, 0), J3(0, 1), J3(0, 2) };
+    J3 axis_angle[3] = {J3(theta, 0), J3(0, 1), J3(0, 2)};
     J3 quaternion[4];
     J3 expected[4] = {
-        MakeJ3(cos(theta/2), -sin(theta/2)/2, 0, 0),
-        MakeJ3(sin(theta/2), cos(theta/2)/2, 0, 0),
-        MakeJ3(0, 0, sin(theta/2)/theta, 0),
-        MakeJ3(0, 0, 0, sin(theta/2)/theta),
+        MakeJ3(cos(theta / 2), -sin(theta / 2) / 2, 0, 0),
+        MakeJ3(sin(theta / 2), cos(theta / 2) / 2, 0, 0),
+        MakeJ3(0, 0, sin(theta / 2) / theta, 0),
+        MakeJ3(0, 0, 0, sin(theta / 2) / theta),
     };
     AngleAxisToQuaternion(axis_angle, quaternion);
     ExpectJetArraysClose<4, 3>(quaternion, expected);
   }
 }
 
-
 // Test that conversion works for very small angles when jets are used.
 TEST(Rotation, TinyAngleAxisToQuaternionForJets) {
   // Examine tiny x rotations that extend all the way to where
   // underflow occurs.
   for (int i = kSmallTinyCutoff; i >= kTinyZeroLimit; i--) {
     double theta = pow(10.0, i);
-    J3 axis_angle[3] = { J3(theta, 0), J3(0, 1), J3(0, 2) };
+    J3 axis_angle[3] = {J3(theta, 0), J3(0, 1), J3(0, 2)};
     J3 quaternion[4];
     // To avoid loss of precision in the test itself,
     // a finite expansion is used here, which will
@@ -788,7 +799,7 @@
 
 // Test that derivatives are correct for zero rotation.
 TEST(Rotation, ZeroAngleAxisToQuaternionForJets) {
-  J3 axis_angle[3] = { J3(0, 0), J3(0, 1), J3(0, 2) };
+  J3 axis_angle[3] = {J3(0, 0), J3(0, 1), J3(0, 2)};
   J3 quaternion[4];
   J3 expected[4] = {
       MakeJ3(1.0, 0, 0, 0),
@@ -808,13 +819,15 @@
     double theta = pow(10.0, i);
     double s = sin(theta);
     double c = cos(theta);
-    J4 quaternion[4] = { J4(c, 0), J4(s, 1), J4(0, 2), J4(0, 3) };
+    J4 quaternion[4] = {J4(c, 0), J4(s, 1), J4(0, 2), J4(0, 3)};
     J4 axis_angle[3];
+    // clang-format off
     J4 expected[3] = {
         MakeJ4(2*theta, -2*s, 2*c,  0,         0),
         MakeJ4(0,        0,   0,    2*theta/s, 0),
         MakeJ4(0,        0,   0,    0,         2*theta/s),
     };
+    // clang-format on
     QuaternionToAngleAxis(quaternion, axis_angle);
     ExpectJetArraysClose<3, 4>(axis_angle, expected);
   }
@@ -828,16 +841,18 @@
     double theta = pow(10.0, i);
     double s = sin(theta);
     double c = cos(theta);
-    J4 quaternion[4] = { J4(c, 0), J4(s, 1), J4(0, 2), J4(0, 3) };
+    J4 quaternion[4] = {J4(c, 0), J4(s, 1), J4(0, 2), J4(0, 3)};
     J4 axis_angle[3];
     // To avoid loss of precision in the test itself,
     // a finite expansion is used here, which will
     // be exact up to machine precision for the test values used.
+    // clang-format off
     J4 expected[3] = {
         MakeJ4(2*theta, -2*s, 2.0, 0,   0),
         MakeJ4(0,        0,   0,   2.0, 0),
         MakeJ4(0,        0,   0,   0,   2.0),
     };
+    // clang-format on
     QuaternionToAngleAxis(quaternion, axis_angle);
     ExpectJetArraysClose<3, 4>(axis_angle, expected);
   }
@@ -845,7 +860,7 @@
 
 // Test that conversion works for no rotation.
 TEST(Rotation, ZeroQuaternionToAngleAxisForJets) {
-  J4 quaternion[4] = { J4(1, 0), J4(0, 1), J4(0, 2), J4(0, 3) };
+  J4 quaternion[4] = {J4(1, 0), J4(0, 1), J4(0, 2), J4(0, 3)};
   J4 axis_angle[3];
   J4 expected[3] = {
       MakeJ4(0, 0, 2.0, 0, 0),
@@ -859,20 +874,22 @@
 TEST(Quaternion, RotatePointGivesSameAnswerAsRotationByMatrixCanned) {
   // Canned data generated in octave.
   double const q[4] = {
-    +0.1956830471754074,
-    -0.0150618562474847,
-    +0.7634572982788086,
-    -0.3019454777240753,
+      +0.1956830471754074,
+      -0.0150618562474847,
+      +0.7634572982788086,
+      -0.3019454777240753,
   };
-  double const Q[3][3] = {  // Scaled rotation matrix.
-    { -0.6355194033477252,  0.0951730541682254,  0.3078870197911186 },
-    { -0.1411693904792992,  0.5297609702153905, -0.4551502574482019 },
-    { -0.2896955822708862, -0.4669396571547050, -0.4536309793389248 },
+  double const Q[3][3] = {
+      // Scaled rotation matrix.
+      {-0.6355194033477252, +0.0951730541682254, +0.3078870197911186},
+      {-0.1411693904792992, +0.5297609702153905, -0.4551502574482019},
+      {-0.2896955822708862, -0.4669396571547050, -0.4536309793389248},
   };
-  double const R[3][3] = {  // With unit rows and columns.
-    { -0.8918859164053080,  0.1335655625725649,  0.4320876677394745 },
-    { -0.1981166751680096,  0.7434648665444399, -0.6387564287225856 },
-    { -0.4065578619806013, -0.6553016349046693, -0.6366242786393164 },
+  double const R[3][3] = {
+      // With unit rows and columns.
+      {-0.8918859164053080, +0.1335655625725649, +0.4320876677394745},
+      {-0.1981166751680096, +0.7434648665444399, -0.6387564287225856},
+      {-0.4065578619806013, -0.6553016349046693, -0.6366242786393164},
   };
 
   // Compute R from q and compare to known answer.
@@ -885,19 +902,18 @@
   ExpectArraysClose(9, R[0], Rq[0], kTolerance);
 }
 
-
 TEST(Quaternion, RotatePointGivesSameAnswerAsRotationByMatrix) {
   // Rotation defined by a unit quaternion.
   double const q[4] = {
-    0.2318160216097109,
-    -0.0178430356832060,
-    0.9044300776717159,
-    -0.3576998641394597,
+      +0.2318160216097109,
+      -0.0178430356832060,
+      +0.9044300776717159,
+      -0.3576998641394597,
   };
   double const p[3] = {
-    +0.11,
-    -13.15,
-    1.17,
+      +0.11,
+      -13.15,
+      1.17,
   };
 
   double R[3 * 3];
@@ -907,11 +923,10 @@
   UnitQuaternionRotatePoint(q, p, result1);
 
   double result2[3];
-  VectorRef(result2, 3) = ConstMatrixRef(R, 3, 3)* ConstVectorRef(p, 3);
+  VectorRef(result2, 3) = ConstMatrixRef(R, 3, 3) * ConstVectorRef(p, 3);
   ExpectArraysClose(3, result1, result2, kTolerance);
 }
 
-
 // Verify that (a * b) * c == a * (b * c).
 TEST(Quaternion, MultiplicationIsAssociative) {
   double a[4];
@@ -939,7 +954,6 @@
   ASSERT_NEAR(ab_c[3], a_bc[3], kTolerance);
 }
 
-
 TEST(AngleAxis, RotatePointGivesSameAnswerAsRotationMatrix) {
   double angle_axis[3];
   double R[9];
@@ -969,6 +983,7 @@
 
       AngleAxisRotatePoint(angle_axis, p, angle_axis_rotated_p);
       for (int k = 0; k < 3; ++k) {
+        // clang-format off
         EXPECT_NEAR(rotation_matrix_rotated_p[k],
                     angle_axis_rotated_p[k],
                     kTolerance) << "p: " << p[0]
@@ -977,6 +992,7 @@
                                 << " angle_axis: " << angle_axis[0]
                                 << " " << angle_axis[1]
                                 << " " << angle_axis[2];
+        // clang-format on
       }
     }
   }
@@ -997,7 +1013,7 @@
       norm2 = angle_axis[k] * angle_axis[k];
     }
 
-    double theta = (2.0 * i * 0.0001  - 1.0) * 1e-16;
+    double theta = (2.0 * i * 0.0001 - 1.0) * 1e-16;
     const double inv_norm = theta / sqrt(norm2);
     for (int k = 0; k < 3; ++k) {
       angle_axis[k] *= inv_norm;
@@ -1010,6 +1026,7 @@
 
     AngleAxisRotatePoint(angle_axis, p, angle_axis_rotated_p);
     for (int k = 0; k < 3; ++k) {
+      // clang-format off
       EXPECT_NEAR(rotation_matrix_rotated_p[k],
                   angle_axis_rotated_p[k],
                   kTolerance) << "p: " << p[0]
@@ -1018,14 +1035,15 @@
                               << " angle_axis: " << angle_axis[0]
                               << " " << angle_axis[1]
                               << " " << angle_axis[2];
+      // clang-format on
     }
   }
 }
 
 TEST(MatrixAdapter, RowMajor3x3ReturnTypeAndAccessIsCorrect) {
-  double array[9] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 };
-  const float const_array[9] =
-      { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f };
+  double array[9] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
+  const float const_array[9] = {
+      1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f};
   MatrixAdapter<double, 3, 1> A = RowMajorAdapter3x3(array);
   MatrixAdapter<const float, 3, 1> B = RowMajorAdapter3x3(const_array);
 
@@ -1033,16 +1051,16 @@
     for (int j = 0; j < 3; ++j) {
       // The values are integers from 1 to 9, so equality tests are appropriate
       // even for float and double values.
-      EXPECT_EQ(A(i, j), array[3*i+j]);
-      EXPECT_EQ(B(i, j), const_array[3*i+j]);
+      EXPECT_EQ(A(i, j), array[3 * i + j]);
+      EXPECT_EQ(B(i, j), const_array[3 * i + j]);
     }
   }
 }
 
 TEST(MatrixAdapter, ColumnMajor3x3ReturnTypeAndAccessIsCorrect) {
-  double array[9] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 };
-  const float const_array[9] =
-      { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f };
+  double array[9] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
+  const float const_array[9] = {
+      1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f};
   MatrixAdapter<double, 1, 3> A = ColumnMajorAdapter3x3(array);
   MatrixAdapter<const float, 1, 3> B = ColumnMajorAdapter3x3(const_array);
 
@@ -1050,29 +1068,33 @@
     for (int j = 0; j < 3; ++j) {
       // The values are integers from 1 to 9, so equality tests are
       // appropriate even for float and double values.
-      EXPECT_EQ(A(i, j), array[3*j+i]);
-      EXPECT_EQ(B(i, j), const_array[3*j+i]);
+      EXPECT_EQ(A(i, j), array[3 * j + i]);
+      EXPECT_EQ(B(i, j), const_array[3 * j + i]);
     }
   }
 }
 
 TEST(MatrixAdapter, RowMajor2x4IsCorrect) {
-  const int expected[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+  const int expected[8] = {1, 2, 3, 4, 5, 6, 7, 8};
   int array[8];
   MatrixAdapter<int, 4, 1> M(array);
+  // clang-format off
   M(0, 0) = 1; M(0, 1) = 2; M(0, 2) = 3; M(0, 3) = 4;
   M(1, 0) = 5; M(1, 1) = 6; M(1, 2) = 7; M(1, 3) = 8;
+  // clang-format on
   for (int k = 0; k < 8; ++k) {
     EXPECT_EQ(array[k], expected[k]);
   }
 }
 
 TEST(MatrixAdapter, ColumnMajor2x4IsCorrect) {
-  const int expected[8] = { 1, 5, 2, 6, 3, 7, 4, 8 };
+  const int expected[8] = {1, 5, 2, 6, 3, 7, 4, 8};
   int array[8];
   MatrixAdapter<int, 1, 2> M(array);
+  // clang-format off
   M(0, 0) = 1; M(0, 1) = 2; M(0, 2) = 3; M(0, 3) = 4;
   M(1, 0) = 5; M(1, 1) = 6; M(1, 2) = 7; M(1, 3) = 8;
+  // clang-format on
   for (int k = 0; k < 8; ++k) {
     EXPECT_EQ(array[k], expected[k]);
   }
@@ -1080,11 +1102,13 @@
 
 TEST(RotationMatrixToAngleAxis, NearPiExampleOneFromTobiasStrauss) {
   // Example from Tobias Strauss
+  // clang-format off
   const double rotation_matrix[] = {
     -0.999807135425239,    -0.0128154391194470,   -0.0148814136745799,
     -0.0128154391194470,   -0.148441438622958,     0.988838158557669,
     -0.0148814136745799,    0.988838158557669,     0.148248574048196
   };
+  // clang-format on
 
   double angle_axis[3];
   RotationMatrixToAngleAxis(RowMajorAdapter3x3(rotation_matrix), angle_axis);
@@ -1093,9 +1117,9 @@
   EXPECT_THAT(rotation_matrix, IsNear3x3Matrix(round_trip));
 }
 
-void CheckRotationMatrixToAngleAxisRoundTrip(const double theta,
-                                             const double phi,
-                                             const double angle) {
+static void CheckRotationMatrixToAngleAxisRoundTrip(const double theta,
+                                                    const double phi,
+                                                    const double angle) {
   double angle_axis[3];
   angle_axis[0] = angle * sin(phi) * cos(theta);
   angle_axis[1] = angle * sin(phi) * sin(theta);
diff --git a/internal/ceres/schur_complement_solver.cc b/internal/ceres/schur_complement_solver.cc
index 19f5b06..65e7854 100644
--- a/internal/ceres/schur_complement_solver.cc
+++ b/internal/ceres/schur_complement_solver.cc
@@ -67,23 +67,22 @@
  public:
   explicit BlockRandomAccessSparseMatrixAdapter(
       const BlockRandomAccessSparseMatrix& m)
-      : m_(m) {
-  }
+      : m_(m) {}
 
   virtual ~BlockRandomAccessSparseMatrixAdapter() {}
 
   // y = y + Ax;
-  virtual void RightMultiply(const double* x, double* y) const {
+  void RightMultiply(const double* x, double* y) const final {
     m_.SymmetricRightMultiply(x, y);
   }
 
   // y = y + A'x;
-  virtual void LeftMultiply(const double* x, double* y) const {
+  void LeftMultiply(const double* x, double* y) const final {
     m_.SymmetricRightMultiply(x, y);
   }
 
-  virtual int num_rows() const { return m_.num_rows(); }
-  virtual int num_cols() const { return m_.num_rows(); }
+  int num_rows() const final { return m_.num_rows(); }
+  int num_cols() const final { return m_.num_rows(); }
 
  private:
   const BlockRandomAccessSparseMatrix& m_;
@@ -93,29 +92,28 @@
  public:
   explicit BlockRandomAccessDiagonalMatrixAdapter(
       const BlockRandomAccessDiagonalMatrix& m)
-      : m_(m) {
-  }
+      : m_(m) {}
 
   virtual ~BlockRandomAccessDiagonalMatrixAdapter() {}
 
   // y = y + Ax;
-  virtual void RightMultiply(const double* x, double* y) const {
+  void RightMultiply(const double* x, double* y) const final {
     m_.RightMultiply(x, y);
   }
 
   // y = y + A'x;
-  virtual void LeftMultiply(const double* x, double* y) const {
+  void LeftMultiply(const double* x, double* y) const final {
     m_.RightMultiply(x, y);
   }
 
-  virtual int num_rows() const { return m_.num_rows(); }
-  virtual int num_cols() const { return m_.num_rows(); }
+  int num_rows() const final { return m_.num_rows(); }
+  int num_cols() const final { return m_.num_rows(); }
 
  private:
   const BlockRandomAccessDiagonalMatrix& m_;
 };
 
-} // namespace
+}  // namespace
 
 LinearSolver::Summary SchurComplementSolver::SolveImpl(
     BlockSparseMatrix* A,
@@ -124,24 +122,43 @@
     double* x) {
   EventLogger event_logger("SchurComplementSolver::Solve");
 
+  const CompressedRowBlockStructure* bs = A->block_structure();
   if (eliminator_.get() == NULL) {
-    InitStorage(A->block_structure());
-    DetectStructure(*A->block_structure(),
-                    options_.elimination_groups[0],
+    const int num_eliminate_blocks = options_.elimination_groups[0];
+    const int num_f_blocks = bs->cols.size() - num_eliminate_blocks;
+
+    InitStorage(bs);
+    DetectStructure(*bs,
+                    num_eliminate_blocks,
                     &options_.row_block_size,
                     &options_.e_block_size,
                     &options_.f_block_size);
-    eliminator_.reset(SchurEliminatorBase::Create(options_));
-    CHECK(eliminator_ != nullptr);
+
+    // For the special case of the static structure <2,3,6> with
+    // exactly one f block use the SchurEliminatorForOneFBlock.
+    //
+    // TODO(sameeragarwal): A more scalable template specialization
+    // mechanism that does not cause binary bloat.
+    if (options_.row_block_size == 2 && options_.e_block_size == 3 &&
+        options_.f_block_size == 6 && num_f_blocks == 1) {
+      eliminator_.reset(new SchurEliminatorForOneFBlock<2, 3, 6>);
+    } else {
+      eliminator_.reset(SchurEliminatorBase::Create(options_));
+    }
+
+    CHECK(eliminator_);
     const bool kFullRankETE = true;
-    eliminator_->Init(
-        options_.elimination_groups[0], kFullRankETE, A->block_structure());
-  };
+    eliminator_->Init(num_eliminate_blocks, kFullRankETE, bs);
+  }
 
   std::fill(x, x + A->num_cols(), 0.0);
   event_logger.AddEvent("Setup");
 
-  eliminator_->Eliminate(A, b, per_solve_options.D, lhs_.get(), rhs_.get());
+  eliminator_->Eliminate(BlockSparseMatrixData(*A),
+                         b,
+                         per_solve_options.D,
+                         lhs_.get(),
+                         rhs_.get());
   event_logger.AddEvent("Eliminate");
 
   double* reduced_solution = x + A->num_cols() - lhs_->num_cols();
@@ -150,7 +167,8 @@
   event_logger.AddEvent("ReducedSolve");
 
   if (summary.termination_type == LINEAR_SOLVER_SUCCESS) {
-    eliminator_->BackSubstitute(A, b, per_solve_options.D, reduced_solution, x);
+    eliminator_->BackSubstitute(
+        BlockSparseMatrixData(*A), b, per_solve_options.D, reduced_solution, x);
     event_logger.AddEvent("BackSubstitute");
   }
 
@@ -165,9 +183,7 @@
   const int num_col_blocks = bs->cols.size();
 
   vector<int> blocks(num_col_blocks - num_eliminate_blocks, 0);
-  for (int i = num_eliminate_blocks, j = 0;
-       i < num_col_blocks;
-       ++i, ++j) {
+  for (int i = num_eliminate_blocks, j = 0; i < num_col_blocks; ++i, ++j) {
     blocks[j] = bs->cols[i].size;
   }
 
@@ -178,10 +194,8 @@
 // Solve the system Sx = r, assuming that the matrix S is stored in a
 // BlockRandomAccessDenseMatrix. The linear system is solved using
 // Eigen's Cholesky factorization.
-LinearSolver::Summary
-DenseSchurComplementSolver::SolveReducedLinearSystem(
-    const LinearSolver::PerSolveOptions& per_solve_options,
-    double* solution) {
+LinearSolver::Summary DenseSchurComplementSolver::SolveReducedLinearSystem(
+    const LinearSolver::PerSolveOptions& per_solve_options, double* solution) {
   LinearSolver::Summary summary;
   summary.num_iterations = 0;
   summary.termination_type = LINEAR_SOLVER_SUCCESS;
@@ -202,8 +216,8 @@
   if (options().dense_linear_algebra_library_type == EIGEN) {
     Eigen::LLT<Matrix, Eigen::Upper> llt =
         ConstMatrixRef(m->values(), num_rows, num_rows)
-        .selfadjointView<Eigen::Upper>()
-        .llt();
+            .selfadjointView<Eigen::Upper>()
+            .llt();
     if (llt.info() != Eigen::Success) {
       summary.termination_type = LINEAR_SOLVER_FAILURE;
       summary.message =
@@ -214,11 +228,8 @@
     VectorRef(solution, num_rows) = llt.solve(ConstVectorRef(rhs(), num_rows));
   } else {
     VectorRef(solution, num_rows) = ConstVectorRef(rhs(), num_rows);
-    summary.termination_type =
-        LAPACK::SolveInPlaceUsingCholesky(num_rows,
-                                          m->values(),
-                                          solution,
-                                          &summary.message);
+    summary.termination_type = LAPACK::SolveInPlaceUsingCholesky(
+        num_rows, m->values(), solution, &summary.message);
   }
 
   return summary;
@@ -232,8 +243,7 @@
   }
 }
 
-SparseSchurComplementSolver::~SparseSchurComplementSolver() {
-}
+SparseSchurComplementSolver::~SparseSchurComplementSolver() {}
 
 // Determine the non-zero blocks in the Schur Complement matrix, and
 // initialize a BlockRandomAccessSparseMatrix object.
@@ -347,8 +357,7 @@
 
 LinearSolver::Summary
 SparseSchurComplementSolver::SolveReducedLinearSystemUsingConjugateGradients(
-    const LinearSolver::PerSolveOptions& per_solve_options,
-    double* solution) {
+    const LinearSolver::PerSolveOptions& per_solve_options, double* solution) {
   CHECK(options().use_explicit_schur_complement);
   const int num_rows = lhs()->num_rows();
   // The case where there are no f blocks, and the system is block
@@ -368,13 +377,12 @@
     preconditioner_.reset(new BlockRandomAccessDiagonalMatrix(blocks_));
   }
 
-  BlockRandomAccessSparseMatrix* sc =
-      down_cast<BlockRandomAccessSparseMatrix*>(
-          const_cast<BlockRandomAccessMatrix*>(lhs()));
+  BlockRandomAccessSparseMatrix* sc = down_cast<BlockRandomAccessSparseMatrix*>(
+      const_cast<BlockRandomAccessMatrix*>(lhs()));
 
   // Extract block diagonal from the Schur complement to construct the
   // schur_jacobi preconditioner.
-  for (int i = 0; i  < blocks_.size(); ++i) {
+  for (int i = 0; i < blocks_.size(); ++i) {
     const int block_size = blocks_[i];
 
     int sc_r, sc_c, sc_row_stride, sc_col_stride;
@@ -401,7 +409,6 @@
   std::unique_ptr<LinearOperator> preconditioner_adapter(
       new BlockRandomAccessDiagonalMatrixAdapter(*preconditioner_));
 
-
   LinearSolver::Options cg_options;
   cg_options.min_num_iterations = options().min_num_iterations;
   cg_options.max_num_iterations = options().max_num_iterations;
@@ -412,10 +419,8 @@
   cg_per_solve_options.q_tolerance = per_solve_options.q_tolerance;
   cg_per_solve_options.preconditioner = preconditioner_adapter.get();
 
-  return cg_solver.Solve(lhs_adapter.get(),
-                         rhs(),
-                         cg_per_solve_options,
-                         solution);
+  return cg_solver.Solve(
+      lhs_adapter.get(), rhs(), cg_per_solve_options, solution);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/schur_complement_solver.h b/internal/ceres/schur_complement_solver.h
index 16ffb8c..3bfa22f 100644
--- a/internal/ceres/schur_complement_solver.h
+++ b/internal/ceres/schur_complement_solver.h
@@ -46,8 +46,8 @@
 #include "ceres/types.h"
 
 #ifdef CERES_USE_EIGEN_SPARSE
-#include "Eigen/SparseCholesky"
 #include "Eigen/OrderingMethods"
+#include "Eigen/SparseCholesky"
 #endif
 
 namespace ceres {
@@ -107,7 +107,8 @@
 // set to DENSE_SCHUR and SPARSE_SCHUR
 // respectively. LinearSolver::Options::elimination_groups[0] should
 // be at least 1.
-class SchurComplementSolver : public BlockSparseMatrixSolver {
+class CERES_EXPORT_INTERNAL SchurComplementSolver
+    : public BlockSparseMatrixSolver {
  public:
   explicit SchurComplementSolver(const LinearSolver::Options& options)
       : options_(options) {
@@ -120,11 +121,11 @@
 
   // LinearSolver methods
   virtual ~SchurComplementSolver() {}
-  virtual LinearSolver::Summary SolveImpl(
+  LinearSolver::Summary SolveImpl(
       BlockSparseMatrix* A,
       const double* b,
       const LinearSolver::PerSolveOptions& per_solve_options,
-      double* x);
+      double* x) override;
 
  protected:
   const LinearSolver::Options& options() const { return options_; }
@@ -158,10 +159,10 @@
   virtual ~DenseSchurComplementSolver() {}
 
  private:
-  virtual void InitStorage(const CompressedRowBlockStructure* bs);
-  virtual LinearSolver::Summary SolveReducedLinearSystem(
+  void InitStorage(const CompressedRowBlockStructure* bs) final;
+  LinearSolver::Summary SolveReducedLinearSystem(
       const LinearSolver::PerSolveOptions& per_solve_options,
-      double* solution);
+      double* solution) final;
 };
 
 // Sparse Cholesky factorization based solver.
@@ -174,13 +175,12 @@
   virtual ~SparseSchurComplementSolver();
 
  private:
-  virtual void InitStorage(const CompressedRowBlockStructure* bs);
-  virtual LinearSolver::Summary SolveReducedLinearSystem(
+  void InitStorage(const CompressedRowBlockStructure* bs) final;
+  LinearSolver::Summary SolveReducedLinearSystem(
       const LinearSolver::PerSolveOptions& per_solve_options,
-      double* solution);
+      double* solution) final;
   LinearSolver::Summary SolveReducedLinearSystemUsingConjugateGradients(
-      const LinearSolver::PerSolveOptions& per_solve_options,
-      double* solution);
+      const LinearSolver::PerSolveOptions& per_solve_options, double* solution);
 
   // Size of the blocks in the Schur complement.
   std::vector<int> blocks_;
diff --git a/internal/ceres/schur_complement_solver_test.cc b/internal/ceres/schur_complement_solver_test.cc
index 23d3674..550733e 100644
--- a/internal/ceres/schur_complement_solver_test.cc
+++ b/internal/ceres/schur_complement_solver_test.cc
@@ -74,9 +74,8 @@
 
     std::unique_ptr<LinearSolver> qr(LinearSolver::Create(options));
 
-    TripletSparseMatrix triplet_A(A->num_rows(),
-                                  A->num_cols(),
-                                  A->num_nonzeros());
+    TripletSparseMatrix triplet_A(
+        A->num_rows(), A->num_cols(), A->num_nonzeros());
     A->ToTripletSparseMatrix(&triplet_A);
 
     // Gold standard solutions using dense QR factorization.
@@ -99,8 +98,8 @@
     SetUpFromProblemId(problem_id);
     LinearSolver::Options options;
     options.elimination_groups.push_back(num_eliminate_blocks);
-    options.elimination_groups.push_back(
-        A->block_structure()->cols.size() - num_eliminate_blocks);
+    options.elimination_groups.push_back(A->block_structure()->cols.size() -
+                                         num_eliminate_blocks);
     options.type = linear_solver_type;
     options.dense_linear_algebra_library_type =
         dense_linear_algebra_library_type;
@@ -127,7 +126,6 @@
     EXPECT_EQ(summary.termination_type, LINEAR_SOLVER_SUCCESS);
 
     if (regularization) {
-
       ASSERT_NEAR((sol_d - x).norm() / num_cols, 0, 1e-10)
           << "Regularized Expected solution: " << sol_d.transpose()
           << " Actual solution: " << x.transpose();
@@ -207,42 +205,40 @@
 #endif  // CERES_NO_SUITESPARSE
 
 #ifndef CERES_NO_CXSPARSE
-TEST_F(SchurComplementSolverTest,
-       SparseSchurWithCXSparseSmallProblem) {
+TEST_F(SchurComplementSolverTest, SparseSchurWithCXSparseSmallProblem) {
   ComputeAndCompareSolutions(2, false, SPARSE_SCHUR, EIGEN, CX_SPARSE, true);
   ComputeAndCompareSolutions(2, true, SPARSE_SCHUR, EIGEN, CX_SPARSE, true);
 }
 
-TEST_F(SchurComplementSolverTest,
-       SparseSchurWithCXSparseLargeProblem) {
+TEST_F(SchurComplementSolverTest, SparseSchurWithCXSparseLargeProblem) {
   ComputeAndCompareSolutions(3, false, SPARSE_SCHUR, EIGEN, CX_SPARSE, true);
   ComputeAndCompareSolutions(3, true, SPARSE_SCHUR, EIGEN, CX_SPARSE, true);
 }
 #endif  // CERES_NO_CXSPARSE
 
 #ifndef CERES_NO_ACCELERATE_SPARSE
-TEST_F(SchurComplementSolverTest,
-       SparseSchurWithAccelerateSparseSmallProblem) {
-  ComputeAndCompareSolutions(2, false, SPARSE_SCHUR, EIGEN, ACCELERATE_SPARSE, true);
-  ComputeAndCompareSolutions(2, true, SPARSE_SCHUR, EIGEN, ACCELERATE_SPARSE, true);
+TEST_F(SchurComplementSolverTest, SparseSchurWithAccelerateSparseSmallProblem) {
+  ComputeAndCompareSolutions(
+      2, false, SPARSE_SCHUR, EIGEN, ACCELERATE_SPARSE, true);
+  ComputeAndCompareSolutions(
+      2, true, SPARSE_SCHUR, EIGEN, ACCELERATE_SPARSE, true);
 }
 
-TEST_F(SchurComplementSolverTest,
-       SparseSchurWithAccelerateSparseLargeProblem) {
-  ComputeAndCompareSolutions(3, false, SPARSE_SCHUR, EIGEN, ACCELERATE_SPARSE, true);
-  ComputeAndCompareSolutions(3, true, SPARSE_SCHUR, EIGEN, ACCELERATE_SPARSE, true);
+TEST_F(SchurComplementSolverTest, SparseSchurWithAccelerateSparseLargeProblem) {
+  ComputeAndCompareSolutions(
+      3, false, SPARSE_SCHUR, EIGEN, ACCELERATE_SPARSE, true);
+  ComputeAndCompareSolutions(
+      3, true, SPARSE_SCHUR, EIGEN, ACCELERATE_SPARSE, true);
 }
 #endif  // CERES_NO_ACCELERATE_SPARSE
 
 #ifdef CERES_USE_EIGEN_SPARSE
-TEST_F(SchurComplementSolverTest,
-       SparseSchurWithEigenSparseSmallProblem) {
+TEST_F(SchurComplementSolverTest, SparseSchurWithEigenSparseSmallProblem) {
   ComputeAndCompareSolutions(2, false, SPARSE_SCHUR, EIGEN, EIGEN_SPARSE, true);
   ComputeAndCompareSolutions(2, true, SPARSE_SCHUR, EIGEN, EIGEN_SPARSE, true);
 }
 
-TEST_F(SchurComplementSolverTest,
-       SparseSchurWithEigenSparseLargeProblem) {
+TEST_F(SchurComplementSolverTest, SparseSchurWithEigenSparseLargeProblem) {
   ComputeAndCompareSolutions(3, false, SPARSE_SCHUR, EIGEN, EIGEN_SPARSE, true);
   ComputeAndCompareSolutions(3, true, SPARSE_SCHUR, EIGEN, EIGEN_SPARSE, true);
 }
diff --git a/internal/ceres/schur_eliminator.cc b/internal/ceres/schur_eliminator.cc
index beefa14..613ae95 100644
--- a/internal/ceres/schur_eliminator.cc
+++ b/internal/ceres/schur_eliminator.cc
@@ -41,115 +41,119 @@
 
 #include "ceres/linear_solver.h"
 #include "ceres/schur_eliminator.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
 
-SchurEliminatorBase*
-SchurEliminatorBase::Create(const LinearSolver::Options& options) {
+SchurEliminatorBase* SchurEliminatorBase::Create(
+    const LinearSolver::Options& options) {
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
- if ((options.row_block_size == 2) &&
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 2) &&
      (options.f_block_size == 2)) {
-   return new SchurEliminator<2, 2, 2>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 2, 2>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 2) &&
      (options.f_block_size == 3)) {
-   return new SchurEliminator<2, 2, 3>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 2, 3>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 2) &&
      (options.f_block_size == 4)) {
-   return new SchurEliminator<2, 2, 4>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 2, 4>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 2)) {
-   return new SchurEliminator<2, 2, Eigen::Dynamic>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 2, Eigen::Dynamic>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3) &&
      (options.f_block_size == 3)) {
-   return new SchurEliminator<2, 3, 3>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 3, 3>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3) &&
      (options.f_block_size == 4)) {
-   return new SchurEliminator<2, 3, 4>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 3, 4>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3) &&
      (options.f_block_size == 6)) {
-   return new SchurEliminator<2, 3, 6>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 3, 6>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3) &&
      (options.f_block_size == 9)) {
-   return new SchurEliminator<2, 3, 9>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 3, 9>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3)) {
-   return new SchurEliminator<2, 3, Eigen::Dynamic>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 3, Eigen::Dynamic>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 3)) {
-   return new SchurEliminator<2, 4, 3>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 4, 3>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 4)) {
-   return new SchurEliminator<2, 4, 4>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 4, 4>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 6)) {
-   return new SchurEliminator<2, 4, 6>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 4, 6>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 8)) {
-   return new SchurEliminator<2, 4, 8>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 4, 8>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 9)) {
-   return new SchurEliminator<2, 4, 9>(options);
- }
- if ((options.row_block_size == 2) &&
+    return new SchurEliminator<2, 4, 9>(options);
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4)) {
-   return new SchurEliminator<2, 4, Eigen::Dynamic>(options);
- }
- if (options.row_block_size == 2){
-   return new SchurEliminator<2, Eigen::Dynamic, Eigen::Dynamic>(options);
- }
- if ((options.row_block_size == 4) &&
+    return new SchurEliminator<2, 4, Eigen::Dynamic>(options);
+  }
+  if (options.row_block_size == 2) {
+    return new SchurEliminator<2, Eigen::Dynamic, Eigen::Dynamic>(options);
+  }
+  if ((options.row_block_size == 3) &&
+     (options.e_block_size == 3) &&
+     (options.f_block_size == 3)) {
+    return new SchurEliminator<3, 3, 3>(options);
+  }
+  if ((options.row_block_size == 4) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 2)) {
-   return new SchurEliminator<4, 4, 2>(options);
- }
- if ((options.row_block_size == 4) &&
+    return new SchurEliminator<4, 4, 2>(options);
+  }
+  if ((options.row_block_size == 4) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 3)) {
-   return new SchurEliminator<4, 4, 3>(options);
- }
- if ((options.row_block_size == 4) &&
+    return new SchurEliminator<4, 4, 3>(options);
+  }
+  if ((options.row_block_size == 4) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 4)) {
-   return new SchurEliminator<4, 4, 4>(options);
- }
- if ((options.row_block_size == 4) &&
+    return new SchurEliminator<4, 4, 4>(options);
+  }
+  if ((options.row_block_size == 4) &&
      (options.e_block_size == 4)) {
-   return new SchurEliminator<4, 4, Eigen::Dynamic>(options);
- }
+    return new SchurEliminator<4, 4, Eigen::Dynamic>(options);
+  }
 
 #endif
   VLOG(1) << "Template specializations not found for <"
-          << options.row_block_size << ","
-          << options.e_block_size << ","
+          << options.row_block_size << "," << options.e_block_size << ","
           << options.f_block_size << ">";
-  return new SchurEliminator<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>(options);
+  return new SchurEliminator<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>(
+      options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/schur_eliminator.h b/internal/ceres/schur_eliminator.h
index 11e6eba..42c016e 100644
--- a/internal/ceres/schur_eliminator.h
+++ b/internal/ceres/schur_eliminator.h
@@ -1,5 +1,5 @@
 // Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2015 Google Inc. All rights reserved.
+// Copyright 2019 Google Inc. All rights reserved.
 // http://ceres-solver.org/
 //
 // Redistribution and use in source and binary forms, with or without
@@ -36,10 +36,12 @@
 #include <mutex>
 #include <vector>
 
+#include "Eigen/Dense"
 #include "ceres/block_random_access_matrix.h"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/block_structure.h"
 #include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
 #include "ceres/linear_solver.h"
 
 namespace ceres {
@@ -162,7 +164,7 @@
 // 2008 for an example of such use].
 //
 // Example usage: Please see schur_complement_solver.cc
-class SchurEliminatorBase {
+class CERES_EXPORT_INTERNAL SchurEliminatorBase {
  public:
   virtual ~SchurEliminatorBase() {}
 
@@ -193,7 +195,7 @@
   //
   // Since the Schur complement is a symmetric matrix, only the upper
   // triangular part of the Schur complement is computed.
-  virtual void Eliminate(const BlockSparseMatrix* A,
+  virtual void Eliminate(const BlockSparseMatrixData& A,
                          const double* b,
                          const double* D,
                          BlockRandomAccessMatrix* lhs,
@@ -202,7 +204,7 @@
   // Given values for the variables z in the F block of A, solve for
   // the optimal values of the variables y corresponding to the E
   // block in A.
-  virtual void BackSubstitute(const BlockSparseMatrix* A,
+  virtual void BackSubstitute(const BlockSparseMatrixData& A,
                               const double* b,
                               const double* D,
                               const double* z,
@@ -220,30 +222,29 @@
 // level linear algebra routines.
 template <int kRowBlockSize = Eigen::Dynamic,
           int kEBlockSize = Eigen::Dynamic,
-          int kFBlockSize = Eigen::Dynamic >
+          int kFBlockSize = Eigen::Dynamic>
 class SchurEliminator : public SchurEliminatorBase {
  public:
   explicit SchurEliminator(const LinearSolver::Options& options)
-      : num_threads_(options.num_threads),
-        context_(options.context) {
+      : num_threads_(options.num_threads), context_(options.context) {
     CHECK(context_ != nullptr);
-}
+  }
 
   // SchurEliminatorBase Interface
   virtual ~SchurEliminator();
-  virtual void Init(int num_eliminate_blocks,
-                    bool assume_full_rank_ete,
-                    const CompressedRowBlockStructure* bs);
-  virtual void Eliminate(const BlockSparseMatrix* A,
-                         const double* b,
-                         const double* D,
-                         BlockRandomAccessMatrix* lhs,
-                         double* rhs);
-  virtual void BackSubstitute(const BlockSparseMatrix* A,
-                              const double* b,
-                              const double* D,
-                              const double* z,
-                              double* y);
+  void Init(int num_eliminate_blocks,
+            bool assume_full_rank_ete,
+            const CompressedRowBlockStructure* bs) final;
+  void Eliminate(const BlockSparseMatrixData& A,
+                 const double* b,
+                 const double* D,
+                 BlockRandomAccessMatrix* lhs,
+                 double* rhs) final;
+  void BackSubstitute(const BlockSparseMatrixData& A,
+                      const double* b,
+                      const double* D,
+                      const double* z,
+                      double* y) final;
 
  private:
   // Chunk objects store combinatorial information needed to
@@ -281,7 +282,7 @@
 
   void ChunkDiagonalBlockAndGradient(
       const Chunk& chunk,
-      const BlockSparseMatrix* A,
+      const BlockSparseMatrixData& A,
       const double* b,
       int row_block_counter,
       typename EigenTypes<kEBlockSize, kEBlockSize>::Matrix* eet,
@@ -290,7 +291,7 @@
       BlockRandomAccessMatrix* lhs);
 
   void UpdateRhs(const Chunk& chunk,
-                 const BlockSparseMatrix* A,
+                 const BlockSparseMatrixData& A,
                  const double* b,
                  int row_block_counter,
                  const double* inverse_ete_g,
@@ -302,18 +303,17 @@
                          const double* buffer,
                          const BufferLayoutType& buffer_layout,
                          BlockRandomAccessMatrix* lhs);
-  void EBlockRowOuterProduct(const BlockSparseMatrix* A,
+  void EBlockRowOuterProduct(const BlockSparseMatrixData& A,
                              int row_block_index,
                              BlockRandomAccessMatrix* lhs);
 
+  void NoEBlockRowsUpdate(const BlockSparseMatrixData& A,
+                          const double* b,
+                          int row_block_counter,
+                          BlockRandomAccessMatrix* lhs,
+                          double* rhs);
 
-  void NoEBlockRowsUpdate(const BlockSparseMatrix* A,
-                             const double* b,
-                             int row_block_counter,
-                             BlockRandomAccessMatrix* lhs,
-                             double* rhs);
-
-  void NoEBlockRowOuterProduct(const BlockSparseMatrix* A,
+  void NoEBlockRowOuterProduct(const BlockSparseMatrixData& A,
                                int row_block_index,
                                BlockRandomAccessMatrix* lhs);
 
@@ -357,7 +357,268 @@
 
   // Locks for the blocks in the right hand side of the reduced linear
   // system.
- std::vector<std::mutex*> rhs_locks_;
+  std::vector<std::mutex*> rhs_locks_;
+};
+
+// SchurEliminatorForOneFBlock specializes the SchurEliminatorBase interface for
+// the case where there is exactly one f-block and all three parameters
+// kRowBlockSize, kEBlockSize and KFBlockSize are known at compile time. This is
+// the case for some two view bundle adjustment problems which have very
+// stringent latency requirements.
+//
+// Under these assumptions, we can simplify the more general algorithm
+// implemented by SchurEliminatorImpl significantly. Two of the major
+// contributors to the increased performance are:
+//
+// 1. Simpler loop structure and less use of dynamic memory. Almost everything
+//    is on the stack and benefits from aligned memory as well as fixed sized
+//    vectorization. We are also able to reason about temporaries and control
+//    their lifetimes better.
+// 2. Use of inverse() over llt().solve(Identity).
+template <int kRowBlockSize = Eigen::Dynamic,
+          int kEBlockSize = Eigen::Dynamic,
+          int kFBlockSize = Eigen::Dynamic>
+class SchurEliminatorForOneFBlock : public SchurEliminatorBase {
+ public:
+  virtual ~SchurEliminatorForOneFBlock() {}
+  void Init(int num_eliminate_blocks,
+            bool assume_full_rank_ete,
+            const CompressedRowBlockStructure* bs) override {
+    CHECK_GT(num_eliminate_blocks, 0)
+        << "SchurComplementSolver cannot be initialized with "
+        << "num_eliminate_blocks = 0.";
+    CHECK_EQ(bs->cols.size() - num_eliminate_blocks, 1);
+
+    num_eliminate_blocks_ = num_eliminate_blocks;
+    const int num_row_blocks = bs->rows.size();
+    chunks_.clear();
+    int r = 0;
+    // Iterate over the row blocks of A, and detect the chunks. The
+    // matrix should already have been ordered so that all rows
+    // containing the same y block are vertically contiguous.
+    while (r < num_row_blocks) {
+      const int e_block_id = bs->rows[r].cells.front().block_id;
+      if (e_block_id >= num_eliminate_blocks_) {
+        break;
+      }
+
+      chunks_.push_back(Chunk());
+      Chunk& chunk = chunks_.back();
+      chunk.num_rows = 0;
+      chunk.start = r;
+      // Add to the chunk until the first block in the row is
+      // different than the one in the first row for the chunk.
+      while (r + chunk.num_rows < num_row_blocks) {
+        const CompressedRow& row = bs->rows[r + chunk.num_rows];
+        if (row.cells.front().block_id != e_block_id) {
+          break;
+        }
+        ++chunk.num_rows;
+      }
+      r += chunk.num_rows;
+    }
+
+    const Chunk& last_chunk = chunks_.back();
+    uneliminated_row_begins_ = last_chunk.start + last_chunk.num_rows;
+    e_t_e_inverse_matrices_.resize(kEBlockSize * kEBlockSize * chunks_.size());
+    std::fill(
+        e_t_e_inverse_matrices_.begin(), e_t_e_inverse_matrices_.end(), 0.0);
+  }
+
+  void Eliminate(const BlockSparseMatrixData& A,
+                 const double* b,
+                 const double* D,
+                 BlockRandomAccessMatrix* lhs_bram,
+                 double* rhs_ptr) override {
+    // Since there is only one f-block, we can call GetCell once, and cache its
+    // output.
+    int r, c, row_stride, col_stride;
+    CellInfo* cell_info =
+        lhs_bram->GetCell(0, 0, &r, &c, &row_stride, &col_stride);
+    typename EigenTypes<kFBlockSize, kFBlockSize>::MatrixRef lhs(
+        cell_info->values, kFBlockSize, kFBlockSize);
+    typename EigenTypes<kFBlockSize>::VectorRef rhs(rhs_ptr, kFBlockSize);
+
+    lhs.setZero();
+    rhs.setZero();
+
+    const CompressedRowBlockStructure* bs = A.block_structure();
+    const double* values = A.values();
+
+    // Add the diagonal to the schur complement.
+    if (D != nullptr) {
+      typename EigenTypes<kFBlockSize>::ConstVectorRef diag(
+          D + bs->cols[num_eliminate_blocks_].position, kFBlockSize);
+      lhs.diagonal() = diag.array().square().matrix();
+    }
+
+    Eigen::Matrix<double, kEBlockSize, kFBlockSize> tmp;
+    Eigen::Matrix<double, kEBlockSize, 1> tmp2;
+
+    // The following loop works on a block matrix which looks as follows
+    // (number of rows can be anything):
+    //
+    // [e_1 | f_1] = [b1]
+    // [e_2 | f_2] = [b2]
+    // [e_3 | f_3] = [b3]
+    // [e_4 | f_4] = [b4]
+    //
+    // and computes the following
+    //
+    // e_t_e = sum_i e_i^T * e_i
+    // e_t_e_inverse = inverse(e_t_e)
+    // e_t_f = sum_i e_i^T f_i
+    // e_t_b = sum_i e_i^T b_i
+    // f_t_b = sum_i f_i^T b_i
+    //
+    // lhs += sum_i f_i^T * f_i - e_t_f^T * e_t_e_inverse * e_t_f
+    // rhs += f_t_b - e_t_f^T * e_t_e_inverse * e_t_b
+    for (int i = 0; i < chunks_.size(); ++i) {
+      const Chunk& chunk = chunks_[i];
+      const int e_block_id = bs->rows[chunk.start].cells.front().block_id;
+
+      // Naming covention, e_t_e = e_block.transpose() * e_block;
+      Eigen::Matrix<double, kEBlockSize, kEBlockSize> e_t_e;
+      Eigen::Matrix<double, kEBlockSize, kFBlockSize> e_t_f;
+      Eigen::Matrix<double, kEBlockSize, 1> e_t_b;
+      Eigen::Matrix<double, kFBlockSize, 1> f_t_b;
+
+      // Add the square of the diagonal to e_t_e.
+      if (D != NULL) {
+        const typename EigenTypes<kEBlockSize>::ConstVectorRef diag(
+            D + bs->cols[e_block_id].position, kEBlockSize);
+        e_t_e = diag.array().square().matrix().asDiagonal();
+      } else {
+        e_t_e.setZero();
+      }
+      e_t_f.setZero();
+      e_t_b.setZero();
+      f_t_b.setZero();
+
+      for (int j = 0; j < chunk.num_rows; ++j) {
+        const int row_id = chunk.start + j;
+        const auto& row = bs->rows[row_id];
+        const typename EigenTypes<kRowBlockSize, kEBlockSize>::ConstMatrixRef
+            e_block(values + row.cells[0].position, kRowBlockSize, kEBlockSize);
+        const typename EigenTypes<kRowBlockSize>::ConstVectorRef b_block(
+            b + row.block.position, kRowBlockSize);
+
+        e_t_e.noalias() += e_block.transpose() * e_block;
+        e_t_b.noalias() += e_block.transpose() * b_block;
+
+        if (row.cells.size() == 1) {
+          // There is no f block, so there is nothing more to do.
+          continue;
+        }
+
+        const typename EigenTypes<kRowBlockSize, kFBlockSize>::ConstMatrixRef
+            f_block(values + row.cells[1].position, kRowBlockSize, kFBlockSize);
+        e_t_f.noalias() += e_block.transpose() * f_block;
+        lhs.noalias() += f_block.transpose() * f_block;
+        f_t_b.noalias() += f_block.transpose() * b_block;
+      }
+
+      // BackSubstitute computes the same inverse, and this is the key workload
+      // there, so caching these inverses makes BackSubstitute essentially free.
+      typename EigenTypes<kEBlockSize, kEBlockSize>::MatrixRef e_t_e_inverse(
+          &e_t_e_inverse_matrices_[kEBlockSize * kEBlockSize * i],
+          kEBlockSize,
+          kEBlockSize);
+
+      // e_t_e is a symmetric positive definite matrix, so the standard way to
+      // compute its inverse is via the Cholesky factorization by calling
+      // e_t_e.llt().solve(Identity()). However, the inverse() method even
+      // though it is not optimized for symmetric matrices is significantly
+      // faster for small fixed size (up to 4x4) matrices.
+      //
+      // https://eigen.tuxfamily.org/dox/group__TutorialLinearAlgebra.html#title3
+      e_t_e_inverse.noalias() = e_t_e.inverse();
+
+      // The use of these two pre-allocated tmp vectors saves temporaries in the
+      // expressions for lhs and rhs updates below and has a significant impact
+      // on the performance of this method.
+      tmp.noalias() = e_t_e_inverse * e_t_f;
+      tmp2.noalias() = e_t_e_inverse * e_t_b;
+
+      lhs.noalias() -= e_t_f.transpose() * tmp;
+      rhs.noalias() += f_t_b - e_t_f.transpose() * tmp2;
+    }
+
+    // The rows without any e-blocks can have arbitrary size but only contain
+    // the f-block.
+    //
+    // lhs += f_i^T f_i
+    // rhs += f_i^T b_i
+    for (int row_id = uneliminated_row_begins_; row_id < bs->rows.size();
+         ++row_id) {
+      const auto& row = bs->rows[row_id];
+      const auto& cell = row.cells[0];
+      const typename EigenTypes<Eigen::Dynamic, kFBlockSize>::ConstMatrixRef
+          f_block(values + cell.position, row.block.size, kFBlockSize);
+      const typename EigenTypes<Eigen::Dynamic>::ConstVectorRef b_block(
+          b + row.block.position, row.block.size);
+      lhs.noalias() += f_block.transpose() * f_block;
+      rhs.noalias() += f_block.transpose() * b_block;
+    }
+  }
+
+  // This implementation of BackSubstitute depends on Eliminate being called
+  // before this. SchurComplementSolver always does this.
+  //
+  // y_i = e_t_e_inverse * sum_i e_i^T * (b_i - f_i * z);
+  void BackSubstitute(const BlockSparseMatrixData& A,
+                      const double* b,
+                      const double* D,
+                      const double* z_ptr,
+                      double* y) override {
+    typename EigenTypes<kFBlockSize>::ConstVectorRef z(z_ptr, kFBlockSize);
+    const CompressedRowBlockStructure* bs = A.block_structure();
+    const double* values = A.values();
+    Eigen::Matrix<double, kEBlockSize, 1> tmp;
+    for (int i = 0; i < chunks_.size(); ++i) {
+      const Chunk& chunk = chunks_[i];
+      const int e_block_id = bs->rows[chunk.start].cells.front().block_id;
+      tmp.setZero();
+      for (int j = 0; j < chunk.num_rows; ++j) {
+        const int row_id = chunk.start + j;
+        const auto& row = bs->rows[row_id];
+        const typename EigenTypes<kRowBlockSize, kEBlockSize>::ConstMatrixRef
+            e_block(values + row.cells[0].position, kRowBlockSize, kEBlockSize);
+        const typename EigenTypes<kRowBlockSize>::ConstVectorRef b_block(
+            b + row.block.position, kRowBlockSize);
+
+        if (row.cells.size() == 1) {
+          // There is no f block.
+          tmp += e_block.transpose() * b_block;
+        } else {
+          typename EigenTypes<kRowBlockSize, kFBlockSize>::ConstMatrixRef
+              f_block(
+                  values + row.cells[1].position, kRowBlockSize, kFBlockSize);
+          tmp += e_block.transpose() * (b_block - f_block * z);
+        }
+      }
+
+      typename EigenTypes<kEBlockSize, kEBlockSize>::MatrixRef e_t_e_inverse(
+          &e_t_e_inverse_matrices_[kEBlockSize * kEBlockSize * i],
+          kEBlockSize,
+          kEBlockSize);
+
+      typename EigenTypes<kEBlockSize>::VectorRef y_block(
+          y + bs->cols[e_block_id].position, kEBlockSize);
+      y_block.noalias() = e_t_e_inverse * tmp;
+    }
+  }
+
+ private:
+  struct Chunk {
+    int start = 0;
+    int num_rows = 0;
+  };
+
+  std::vector<Chunk> chunks_;
+  int num_eliminate_blocks_;
+  int uneliminated_row_begins_;
+  std::vector<double> e_t_e_inverse_matrices_;
 };
 
 }  // namespace internal
diff --git a/internal/ceres/schur_eliminator_benchmark.cc b/internal/ceres/schur_eliminator_benchmark.cc
new file mode 100644
index 0000000..6307025
--- /dev/null
+++ b/internal/ceres/schur_eliminator_benchmark.cc
@@ -0,0 +1,222 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2019 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// 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.
+//
+// Authors: sameeragarwal@google.com (Sameer Agarwal)
+
+#include "Eigen/Dense"
+#include "benchmark/benchmark.h"
+#include "ceres/block_random_access_dense_matrix.h"
+#include "ceres/block_sparse_matrix.h"
+#include "ceres/block_structure.h"
+#include "ceres/random.h"
+#include "ceres/schur_eliminator.h"
+
+namespace ceres {
+namespace internal {
+
+constexpr int kRowBlockSize = 2;
+constexpr int kEBlockSize = 3;
+constexpr int kFBlockSize = 6;
+
+class BenchmarkData {
+ public:
+  explicit BenchmarkData(const int num_e_blocks) {
+    CompressedRowBlockStructure* bs = new CompressedRowBlockStructure;
+    bs->cols.resize(num_e_blocks + 1);
+    int col_pos = 0;
+    for (int i = 0; i < num_e_blocks; ++i) {
+      bs->cols[i].position = col_pos;
+      bs->cols[i].size = kEBlockSize;
+      col_pos += kEBlockSize;
+    }
+    bs->cols.back().position = col_pos;
+    bs->cols.back().size = kFBlockSize;
+
+    bs->rows.resize(2 * num_e_blocks);
+    int row_pos = 0;
+    int cell_pos = 0;
+    for (int i = 0; i < num_e_blocks; ++i) {
+      {
+        auto& row = bs->rows[2 * i];
+        row.block.position = row_pos;
+        row.block.size = kRowBlockSize;
+        row_pos += kRowBlockSize;
+        auto& cells = row.cells;
+        cells.resize(2);
+        cells[0].block_id = i;
+        cells[0].position = cell_pos;
+        cell_pos += kRowBlockSize * kEBlockSize;
+        cells[1].block_id = num_e_blocks;
+        cells[1].position = cell_pos;
+        cell_pos += kRowBlockSize * kFBlockSize;
+      }
+      {
+        auto& row = bs->rows[2 * i + 1];
+        row.block.position = row_pos;
+        row.block.size = kRowBlockSize;
+        row_pos += kRowBlockSize;
+        auto& cells = row.cells;
+        cells.resize(1);
+        cells[0].block_id = i;
+        cells[0].position = cell_pos;
+        cell_pos += kRowBlockSize * kEBlockSize;
+      }
+    }
+
+    matrix_.reset(new BlockSparseMatrix(bs));
+    double* values = matrix_->mutable_values();
+    for (int i = 0; i < matrix_->num_nonzeros(); ++i) {
+      values[i] = RandNormal();
+    }
+
+    b_.resize(matrix_->num_rows());
+    b_.setRandom();
+
+    std::vector<int> blocks(1, kFBlockSize);
+    lhs_.reset(new BlockRandomAccessDenseMatrix(blocks));
+    diagonal_.resize(matrix_->num_cols());
+    diagonal_.setOnes();
+    rhs_.resize(kFBlockSize);
+
+    y_.resize(num_e_blocks * kEBlockSize);
+    y_.setZero();
+    z_.resize(kFBlockSize);
+    z_.setOnes();
+  }
+
+  const BlockSparseMatrix& matrix() const { return *matrix_; }
+  const Vector& b() const { return b_; }
+  const Vector& diagonal() const { return diagonal_; }
+  BlockRandomAccessDenseMatrix* mutable_lhs() { return lhs_.get(); }
+  Vector* mutable_rhs() { return &rhs_; }
+  Vector* mutable_y() { return &y_; }
+  Vector* mutable_z() { return &z_; }
+
+ private:
+  std::unique_ptr<BlockSparseMatrix> matrix_;
+  Vector b_;
+  std::unique_ptr<BlockRandomAccessDenseMatrix> lhs_;
+  Vector rhs_;
+  Vector diagonal_;
+  Vector z_;
+  Vector y_;
+};
+
+void BM_SchurEliminatorEliminate(benchmark::State& state) {
+  const int num_e_blocks = state.range(0);
+  BenchmarkData data(num_e_blocks);
+
+  ContextImpl context;
+  LinearSolver::Options linear_solver_options;
+  linear_solver_options.e_block_size = kEBlockSize;
+  linear_solver_options.row_block_size = kRowBlockSize;
+  linear_solver_options.f_block_size = kFBlockSize;
+  linear_solver_options.context = &context;
+  std::unique_ptr<SchurEliminatorBase> eliminator(
+      SchurEliminatorBase::Create(linear_solver_options));
+
+  eliminator->Init(num_e_blocks, true, data.matrix().block_structure());
+  for (auto _ : state) {
+    eliminator->Eliminate(BlockSparseMatrixData(data.matrix()),
+                          data.b().data(),
+                          data.diagonal().data(),
+                          data.mutable_lhs(),
+                          data.mutable_rhs()->data());
+  }
+}
+
+void BM_SchurEliminatorBackSubstitute(benchmark::State& state) {
+  const int num_e_blocks = state.range(0);
+  BenchmarkData data(num_e_blocks);
+
+  ContextImpl context;
+  LinearSolver::Options linear_solver_options;
+  linear_solver_options.e_block_size = kEBlockSize;
+  linear_solver_options.row_block_size = kRowBlockSize;
+  linear_solver_options.f_block_size = kFBlockSize;
+  linear_solver_options.context = &context;
+  std::unique_ptr<SchurEliminatorBase> eliminator(
+      SchurEliminatorBase::Create(linear_solver_options));
+
+  eliminator->Init(num_e_blocks, true, data.matrix().block_structure());
+  eliminator->Eliminate(BlockSparseMatrixData(data.matrix()),
+                        data.b().data(),
+                        data.diagonal().data(),
+                        data.mutable_lhs(),
+                        data.mutable_rhs()->data());
+  for (auto _ : state) {
+    eliminator->BackSubstitute(BlockSparseMatrixData(data.matrix()),
+                               data.b().data(),
+                               data.diagonal().data(),
+                               data.mutable_z()->data(),
+                               data.mutable_y()->data());
+  }
+}
+
+void BM_SchurEliminatorForOneFBlockEliminate(benchmark::State& state) {
+  const int num_e_blocks = state.range(0);
+  BenchmarkData data(num_e_blocks);
+  SchurEliminatorForOneFBlock<2, 3, 6> eliminator;
+  eliminator.Init(num_e_blocks, true, data.matrix().block_structure());
+  for (auto _ : state) {
+    eliminator.Eliminate(BlockSparseMatrixData(data.matrix()),
+                         data.b().data(),
+                         data.diagonal().data(),
+                         data.mutable_lhs(),
+                         data.mutable_rhs()->data());
+  }
+}
+
+void BM_SchurEliminatorForOneFBlockBackSubstitute(benchmark::State& state) {
+  const int num_e_blocks = state.range(0);
+  BenchmarkData data(num_e_blocks);
+  SchurEliminatorForOneFBlock<2, 3, 6> eliminator;
+  eliminator.Init(num_e_blocks, true, data.matrix().block_structure());
+  eliminator.Eliminate(BlockSparseMatrixData(data.matrix()),
+                       data.b().data(),
+                       data.diagonal().data(),
+                       data.mutable_lhs(),
+                       data.mutable_rhs()->data());
+  for (auto _ : state) {
+    eliminator.BackSubstitute(BlockSparseMatrixData(data.matrix()),
+                              data.b().data(),
+                              data.diagonal().data(),
+                              data.mutable_z()->data(),
+                              data.mutable_y()->data());
+  }
+}
+
+BENCHMARK(BM_SchurEliminatorEliminate)->Range(10, 10000);
+BENCHMARK(BM_SchurEliminatorForOneFBlockEliminate)->Range(10, 10000);
+BENCHMARK(BM_SchurEliminatorBackSubstitute)->Range(10, 10000);
+BENCHMARK(BM_SchurEliminatorForOneFBlockBackSubstitute)->Range(10, 10000);
+
+}  // namespace internal
+}  // namespace ceres
+
+BENCHMARK_MAIN();
diff --git a/internal/ceres/schur_eliminator_impl.h b/internal/ceres/schur_eliminator_impl.h
index d754d9d..1f0b4fa 100644
--- a/internal/ceres/schur_eliminator_impl.h
+++ b/internal/ceres/schur_eliminator_impl.h
@@ -46,7 +46,9 @@
 #define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 10
 
 // This include must come before any #ifndef check on Ceres compile options.
+// clang-format off
 #include "ceres/internal/port.h"
+// clang-format on
 
 #include <algorithm>
 #include <map>
@@ -104,6 +106,13 @@
     lhs_num_rows += bs->cols[i].size;
   }
 
+  // TODO(sameeragarwal): Now that we may have subset block structure,
+  // we need to make sure that we account for the fact that somep
+  // point blocks only have a "diagonal" row and nothing more.
+  //
+  // This likely requires a slightly different algorithm, which works
+  // off of the number of elimination blocks.
+
   int r = 0;
   // Iterate over the row blocks of A, and detect the chunks. The
   // matrix should already have been ordered so that all rows
@@ -145,7 +154,7 @@
       ++chunk.size;
     }
 
-    CHECK_GT(chunk.size, 0);
+    CHECK_GT(chunk.size, 0);  // This check will need to be resolved.
     r += chunk.size;
   }
   const Chunk& chunk = chunks_.back();
@@ -167,13 +176,12 @@
 }
 
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
-Eliminate(const BlockSparseMatrix* A,
-          const double* b,
-          const double* D,
-          BlockRandomAccessMatrix* lhs,
-          double* rhs) {
+void SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::Eliminate(
+    const BlockSparseMatrixData& A,
+    const double* b,
+    const double* D,
+    BlockRandomAccessMatrix* lhs,
+    double* rhs) {
   if (lhs->num_rows() > 0) {
     lhs->SetZero();
     if (rhs) {
@@ -181,32 +189,31 @@
     }
   }
 
-  const CompressedRowBlockStructure* bs = A->block_structure();
+  const CompressedRowBlockStructure* bs = A.block_structure();
   const int num_col_blocks = bs->cols.size();
 
   // Add the diagonal to the schur complement.
   if (D != NULL) {
-    ParallelFor(
-        context_,
-        num_eliminate_blocks_,
-        num_col_blocks,
-        num_threads_,
-        [&](int i) {
-          const int block_id = i - num_eliminate_blocks_;
-          int r, c, row_stride, col_stride;
-          CellInfo* cell_info = lhs->GetCell(block_id, block_id, &r, &c,
-                                             &row_stride, &col_stride);
-          if (cell_info != NULL) {
-            const int block_size = bs->cols[i].size;
-            typename EigenTypes<Eigen::Dynamic>::ConstVectorRef diag(
-                D + bs->cols[i].position, block_size);
+    ParallelFor(context_,
+                num_eliminate_blocks_,
+                num_col_blocks,
+                num_threads_,
+                [&](int i) {
+                  const int block_id = i - num_eliminate_blocks_;
+                  int r, c, row_stride, col_stride;
+                  CellInfo* cell_info = lhs->GetCell(
+                      block_id, block_id, &r, &c, &row_stride, &col_stride);
+                  if (cell_info != NULL) {
+                    const int block_size = bs->cols[i].size;
+                    typename EigenTypes<Eigen::Dynamic>::ConstVectorRef diag(
+                        D + bs->cols[i].position, block_size);
 
-            std::lock_guard<std::mutex> l(cell_info->m);
-            MatrixRef m(cell_info->values, row_stride, col_stride);
-            m.block(r, c, block_size, block_size).diagonal() +=
-                diag.array().square().matrix();
-          }
-        });
+                    std::lock_guard<std::mutex> l(cell_info->m);
+                    MatrixRef m(cell_info->values, row_stride, col_stride);
+                    m.block(r, c, block_size, block_size).diagonal() +=
+                        diag.array().square().matrix();
+                  }
+                });
   }
 
   // Eliminate y blocks one chunk at a time.  For each chunk, compute
@@ -235,19 +242,20 @@
 
         VectorRef(buffer, buffer_size_).setZero();
 
-        typename EigenTypes<kEBlockSize, kEBlockSize>::Matrix
-            ete(e_block_size, e_block_size);
+        typename EigenTypes<kEBlockSize, kEBlockSize>::Matrix ete(e_block_size,
+                                                                  e_block_size);
 
         if (D != NULL) {
-          const typename EigenTypes<kEBlockSize>::ConstVectorRef
-              diag(D + bs->cols[e_block_id].position, e_block_size);
+          const typename EigenTypes<kEBlockSize>::ConstVectorRef diag(
+              D + bs->cols[e_block_id].position, e_block_size);
           ete = diag.array().square().matrix().asDiagonal();
         } else {
           ete.setZero();
         }
 
         FixedArray<double, 8> g(e_block_size);
-        typename EigenTypes<kEBlockSize>::VectorRef gref(g.get(), e_block_size);
+        typename EigenTypes<kEBlockSize>::VectorRef gref(g.data(),
+                                                         e_block_size);
         gref.setZero();
 
         // We are going to be computing
@@ -263,7 +271,7 @@
         // in this chunk (g) and add the outer product of the f_blocks to
         // Schur complement (S += F'F).
         ChunkDiagonalBlockAndGradient(
-            chunk, A, b, chunk.start, &ete, g.get(), buffer, lhs);
+            chunk, A, b, chunk.start, &ete, g.data(), buffer, lhs);
 
         // Normally one wouldn't compute the inverse explicitly, but
         // e_block_size will typically be a small number like 3, in
@@ -284,37 +292,32 @@
               inverse_ete.data(),
               e_block_size,
               e_block_size,
-              g.get(),
-              inverse_ete_g.get());
-          UpdateRhs(chunk, A, b, chunk.start, inverse_ete_g.get(), rhs);
+              g.data(),
+              inverse_ete_g.data());
+          UpdateRhs(chunk, A, b, chunk.start, inverse_ete_g.data(), rhs);
         }
 
         // S -= F'E(E'E)^{-1}E'F
         ChunkOuterProduct(
-        thread_id, bs, inverse_ete, buffer, chunk.buffer_layout, lhs);
+            thread_id, bs, inverse_ete, buffer, chunk.buffer_layout, lhs);
       });
 
   // For rows with no e_blocks, the schur complement update reduces to
   // S += F'F.
-  NoEBlockRowsUpdate(A, b,  uneliminated_row_begins_, lhs, rhs);
+  NoEBlockRowsUpdate(A, b, uneliminated_row_begins_, lhs, rhs);
 }
 
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
-BackSubstitute(const BlockSparseMatrix* A,
-               const double* b,
-               const double* D,
-               const double* z,
-               double* y) {
-  const CompressedRowBlockStructure* bs = A->block_structure();
+void SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::BackSubstitute(
+    const BlockSparseMatrixData& A,
+    const double* b,
+    const double* D,
+    const double* z,
+    double* y) {
+  const CompressedRowBlockStructure* bs = A.block_structure();
+  const double* values = A.values();
 
-  ParallelFor(
-      context_,
-      0,
-      int(chunks_.size()),
-      num_threads_,
-      [&](int i) {
+  ParallelFor(context_, 0, int(chunks_.size()), num_threads_, [&](int i) {
     const Chunk& chunk = chunks_[i];
     const int e_block_id = bs->rows[chunk.start].cells.front().block_id;
     const int e_block_size = bs->cols[e_block_id].size;
@@ -322,17 +325,16 @@
     double* y_ptr = y + bs->cols[e_block_id].position;
     typename EigenTypes<kEBlockSize>::VectorRef y_block(y_ptr, e_block_size);
 
-    typename EigenTypes<kEBlockSize, kEBlockSize>::Matrix
-        ete(e_block_size, e_block_size);
+    typename EigenTypes<kEBlockSize, kEBlockSize>::Matrix ete(e_block_size,
+                                                              e_block_size);
     if (D != NULL) {
-      const typename EigenTypes<kEBlockSize>::ConstVectorRef
-          diag(D + bs->cols[e_block_id].position, e_block_size);
+      const typename EigenTypes<kEBlockSize>::ConstVectorRef diag(
+          D + bs->cols[e_block_id].position, e_block_size);
       ete = diag.array().square().matrix().asDiagonal();
     } else {
       ete.setZero();
     }
 
-    const double* values = A->values();
     for (int j = 0; j < chunk.size; ++j) {
       const CompressedRow& row = bs->rows[chunk.start + j];
       const Cell& e_cell = row.cells.front();
@@ -340,24 +342,25 @@
 
       FixedArray<double, 8> sj(row.block.size);
 
-      typename EigenTypes<kRowBlockSize>::VectorRef(sj.get(), row.block.size) =
-          typename EigenTypes<kRowBlockSize>::ConstVectorRef
-          (b + bs->rows[chunk.start + j].block.position, row.block.size);
+      typename EigenTypes<kRowBlockSize>::VectorRef(sj.data(), row.block.size) =
+          typename EigenTypes<kRowBlockSize>::ConstVectorRef(
+              b + bs->rows[chunk.start + j].block.position, row.block.size);
 
       for (int c = 1; c < row.cells.size(); ++c) {
         const int f_block_id = row.cells[c].block_id;
         const int f_block_size = bs->cols[f_block_id].size;
         const int r_block = f_block_id - num_eliminate_blocks_;
 
+        // clang-format off
         MatrixVectorMultiply<kRowBlockSize, kFBlockSize, -1>(
             values + row.cells[c].position, row.block.size, f_block_size,
             z + lhs_row_layout_[r_block],
-            sj.get());
+            sj.data());
       }
 
       MatrixTransposeVectorMultiply<kRowBlockSize, kEBlockSize, 1>(
           values + e_cell.position, row.block.size, e_block_size,
-          sj.get(),
+          sj.data(),
           y_ptr);
 
       MatrixTransposeMatrixMultiply
@@ -365,6 +368,7 @@
           values + e_cell.position, row.block.size, e_block_size,
           values + e_cell.position, row.block.size, e_block_size,
           ete.data(), 0, 0, e_block_size, e_block_size);
+      // clang-format on
     }
 
     y_block =
@@ -376,41 +380,44 @@
 //
 //   F'b - F'E(E'E)^(-1) E'b
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
-UpdateRhs(const Chunk& chunk,
-          const BlockSparseMatrix* A,
-          const double* b,
-          int row_block_counter,
-          const double* inverse_ete_g,
-          double* rhs) {
-  const CompressedRowBlockStructure* bs = A->block_structure();
+void SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::UpdateRhs(
+    const Chunk& chunk,
+    const BlockSparseMatrixData& A,
+    const double* b,
+    int row_block_counter,
+    const double* inverse_ete_g,
+    double* rhs) {
+  const CompressedRowBlockStructure* bs = A.block_structure();
+  const double* values = A.values();
+
   const int e_block_id = bs->rows[chunk.start].cells.front().block_id;
   const int e_block_size = bs->cols[e_block_id].size;
-
   int b_pos = bs->rows[row_block_counter].block.position;
-  const double* values = A->values();
   for (int j = 0; j < chunk.size; ++j) {
     const CompressedRow& row = bs->rows[row_block_counter + j];
     const Cell& e_cell = row.cells.front();
 
     typename EigenTypes<kRowBlockSize>::Vector sj =
-        typename EigenTypes<kRowBlockSize>::ConstVectorRef
-        (b + b_pos, row.block.size);
+        typename EigenTypes<kRowBlockSize>::ConstVectorRef(b + b_pos,
+                                                           row.block.size);
 
+    // clang-format off
     MatrixVectorMultiply<kRowBlockSize, kEBlockSize, -1>(
         values + e_cell.position, row.block.size, e_block_size,
         inverse_ete_g, sj.data());
+    // clang-format on
 
     for (int c = 1; c < row.cells.size(); ++c) {
       const int block_id = row.cells[c].block_id;
       const int block_size = bs->cols[block_id].size;
       const int block = block_id - num_eliminate_blocks_;
       std::lock_guard<std::mutex> l(*rhs_locks_[block]);
+      // clang-format off
       MatrixTransposeVectorMultiply<kRowBlockSize, kFBlockSize, 1>(
           values + row.cells[c].position,
           row.block.size, block_size,
           sj.data(), rhs + lhs_row_layout_[block]);
+      // clang-format on
     }
     b_pos += row.block.size;
   }
@@ -436,18 +443,18 @@
 //
 // and the gradient of the e_block, E'b.
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
-ChunkDiagonalBlockAndGradient(
-    const Chunk& chunk,
-    const BlockSparseMatrix* A,
-    const double* b,
-    int row_block_counter,
-    typename EigenTypes<kEBlockSize, kEBlockSize>::Matrix* ete,
-    double* g,
-    double* buffer,
-    BlockRandomAccessMatrix* lhs) {
-  const CompressedRowBlockStructure* bs = A->block_structure();
+void SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
+    ChunkDiagonalBlockAndGradient(
+        const Chunk& chunk,
+        const BlockSparseMatrixData& A,
+        const double* b,
+        int row_block_counter,
+        typename EigenTypes<kEBlockSize, kEBlockSize>::Matrix* ete,
+        double* g,
+        double* buffer,
+        BlockRandomAccessMatrix* lhs) {
+  const CompressedRowBlockStructure* bs = A.block_structure();
+  const double* values = A.values();
 
   int b_pos = bs->rows[row_block_counter].block.position;
   const int e_block_size = ete->rows();
@@ -456,7 +463,6 @@
   // contribution of its F blocks to the Schur complement, the
   // contribution of its E block to the matrix EE' (ete), and the
   // corresponding block in the gradient vector.
-  const double* values = A->values();
   for (int j = 0; j < chunk.size; ++j) {
     const CompressedRow& row = bs->rows[row_block_counter + j];
 
@@ -466,18 +472,22 @@
 
     // Extract the e_block, ETE += E_i' E_i
     const Cell& e_cell = row.cells.front();
+    // clang-format off
     MatrixTransposeMatrixMultiply
         <kRowBlockSize, kEBlockSize, kRowBlockSize, kEBlockSize, 1>(
             values + e_cell.position, row.block.size, e_block_size,
             values + e_cell.position, row.block.size, e_block_size,
             ete->data(), 0, 0, e_block_size, e_block_size);
+    // clang-format on
 
     if (b) {
       // g += E_i' b_i
+      // clang-format off
       MatrixTransposeVectorMultiply<kRowBlockSize, kEBlockSize, 1>(
           values + e_cell.position, row.block.size, e_block_size,
           b + b_pos,
           g);
+      // clang-format on
     }
 
     // buffer = E'F. This computation is done by iterating over the
@@ -485,13 +495,14 @@
     for (int c = 1; c < row.cells.size(); ++c) {
       const int f_block_id = row.cells[c].block_id;
       const int f_block_size = bs->cols[f_block_id].size;
-      double* buffer_ptr =
-          buffer +  FindOrDie(chunk.buffer_layout, f_block_id);
+      double* buffer_ptr = buffer + FindOrDie(chunk.buffer_layout, f_block_id);
+      // clang-format off
       MatrixTransposeMatrixMultiply
           <kRowBlockSize, kEBlockSize, kRowBlockSize, kFBlockSize, 1>(
           values + e_cell.position, row.block.size, e_block_size,
           values + row.cells[c].position, row.block.size, f_block_size,
           buffer_ptr, 0, 0, e_block_size, f_block_size);
+      // clang-format on
     }
     b_pos += row.block.size;
   }
@@ -502,14 +513,13 @@
 //
 //  S -= F'E(E'E)^{-1}E'F.
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
-ChunkOuterProduct(int thread_id,
-                  const CompressedRowBlockStructure* bs,
-                  const Matrix& inverse_ete,
-                  const double* buffer,
-                  const BufferLayoutType& buffer_layout,
-                  BlockRandomAccessMatrix* lhs) {
+void SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
+    ChunkOuterProduct(int thread_id,
+                      const CompressedRowBlockStructure* bs,
+                      const Matrix& inverse_ete,
+                      const double* buffer,
+                      const BufferLayoutType& buffer_layout,
+                      BlockRandomAccessMatrix* lhs) {
   // This is the most computationally expensive part of this
   // code. Profiling experiments reveal that the bottleneck is not the
   // computation of the right-hand matrix product, but memory
@@ -524,28 +534,31 @@
   for (; it1 != buffer_layout.end(); ++it1) {
     const int block1 = it1->first - num_eliminate_blocks_;
     const int block1_size = bs->cols[it1->first].size;
+    // clang-format off
     MatrixTransposeMatrixMultiply
         <kEBlockSize, kFBlockSize, kEBlockSize, kEBlockSize, 0>(
         buffer + it1->second, e_block_size, block1_size,
         inverse_ete.data(), e_block_size, e_block_size,
         b1_transpose_inverse_ete, 0, 0, block1_size, e_block_size);
+    // clang-format on
 
     BufferLayoutType::const_iterator it2 = it1;
     for (; it2 != buffer_layout.end(); ++it2) {
       const int block2 = it2->first - num_eliminate_blocks_;
 
       int r, c, row_stride, col_stride;
-      CellInfo* cell_info = lhs->GetCell(block1, block2,
-                                         &r, &c,
-                                         &row_stride, &col_stride);
+      CellInfo* cell_info =
+          lhs->GetCell(block1, block2, &r, &c, &row_stride, &col_stride);
       if (cell_info != NULL) {
         const int block2_size = bs->cols[it2->first].size;
         std::lock_guard<std::mutex> l(cell_info->m);
+        // clang-format off
         MatrixMatrixMultiply
             <kFBlockSize, kEBlockSize, kEBlockSize, kFBlockSize, -1>(
                 b1_transpose_inverse_ete, block1_size, e_block_size,
                 buffer  + it2->second, e_block_size, block2_size,
                 cell_info->values, r, c, row_stride, col_stride);
+        // clang-format on
       }
     }
   }
@@ -555,15 +568,14 @@
 // += F'F. This function iterates over the rows of A with no e_block,
 // and calls NoEBlockRowOuterProduct on each row.
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
-NoEBlockRowsUpdate(const BlockSparseMatrix* A,
-                   const double* b,
-                   int row_block_counter,
-                   BlockRandomAccessMatrix* lhs,
-                   double* rhs) {
-  const CompressedRowBlockStructure* bs = A->block_structure();
-  const double* values = A->values();
+void SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
+    NoEBlockRowsUpdate(const BlockSparseMatrixData& A,
+                       const double* b,
+                       int row_block_counter,
+                       BlockRandomAccessMatrix* lhs,
+                       double* rhs) {
+  const CompressedRowBlockStructure* bs = A.block_structure();
+  const double* values = A.values();
   for (; row_block_counter < bs->rows.size(); ++row_block_counter) {
     NoEBlockRowOuterProduct(A, row_block_counter, lhs);
     if (!rhs) {
@@ -574,15 +586,16 @@
       const int block_id = row.cells[c].block_id;
       const int block_size = bs->cols[block_id].size;
       const int block = block_id - num_eliminate_blocks_;
+      // clang-format off
       MatrixTransposeVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
           values + row.cells[c].position, row.block.size, block_size,
           b + row.block.position,
           rhs + lhs_row_layout_[block]);
+      // clang-format on
     }
   }
 }
 
-
 // A row r of A, which has no e_blocks gets added to the Schur
 // Complement as S += r r'. This function is responsible for computing
 // the contribution of a single row r to the Schur complement. It is
@@ -598,32 +611,33 @@
 // dynamic. Since the number of rows without e_blocks is small, the
 // lack of templating is not an issue.
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
-NoEBlockRowOuterProduct(const BlockSparseMatrix* A,
-                        int row_block_index,
-                        BlockRandomAccessMatrix* lhs) {
-  const CompressedRowBlockStructure* bs = A->block_structure();
+void SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
+    NoEBlockRowOuterProduct(const BlockSparseMatrixData& A,
+                            int row_block_index,
+                            BlockRandomAccessMatrix* lhs) {
+  const CompressedRowBlockStructure* bs = A.block_structure();
+  const double* values = A.values();
+
   const CompressedRow& row = bs->rows[row_block_index];
-  const double* values = A->values();
   for (int i = 0; i < row.cells.size(); ++i) {
     const int block1 = row.cells[i].block_id - num_eliminate_blocks_;
     DCHECK_GE(block1, 0);
 
     const int block1_size = bs->cols[row.cells[i].block_id].size;
     int r, c, row_stride, col_stride;
-    CellInfo* cell_info = lhs->GetCell(block1, block1,
-                                       &r, &c,
-                                       &row_stride, &col_stride);
+    CellInfo* cell_info =
+        lhs->GetCell(block1, block1, &r, &c, &row_stride, &col_stride);
     if (cell_info != NULL) {
       std::lock_guard<std::mutex> l(cell_info->m);
       // This multiply currently ignores the fact that this is a
       // symmetric outer product.
+      // clang-format off
       MatrixTransposeMatrixMultiply
           <Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, 1>(
               values + row.cells[i].position, row.block.size, block1_size,
               values + row.cells[i].position, row.block.size, block1_size,
               cell_info->values, r, c, row_stride, col_stride);
+      // clang-format on
     }
 
     for (int j = i + 1; j < row.cells.size(); ++j) {
@@ -631,17 +645,18 @@
       DCHECK_GE(block2, 0);
       DCHECK_LT(block1, block2);
       int r, c, row_stride, col_stride;
-      CellInfo* cell_info = lhs->GetCell(block1, block2,
-                                         &r, &c,
-                                         &row_stride, &col_stride);
+      CellInfo* cell_info =
+          lhs->GetCell(block1, block2, &r, &c, &row_stride, &col_stride);
       if (cell_info != NULL) {
         const int block2_size = bs->cols[row.cells[j].block_id].size;
         std::lock_guard<std::mutex> l(cell_info->m);
+        // clang-format off
         MatrixTransposeMatrixMultiply
             <Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, 1>(
                 values + row.cells[i].position, row.block.size, block1_size,
                 values + row.cells[j].position, row.block.size, block2_size,
                 cell_info->values, r, c, row_stride, col_stride);
+        // clang-format on
       }
     }
   }
@@ -651,31 +666,32 @@
 // function has the same structure as NoEBlockRowOuterProduct, except
 // that this function uses the template parameters.
 template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-void
-SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
-EBlockRowOuterProduct(const BlockSparseMatrix* A,
-                      int row_block_index,
-                      BlockRandomAccessMatrix* lhs) {
-  const CompressedRowBlockStructure* bs = A->block_structure();
+void SchurEliminator<kRowBlockSize, kEBlockSize, kFBlockSize>::
+    EBlockRowOuterProduct(const BlockSparseMatrixData& A,
+                          int row_block_index,
+                          BlockRandomAccessMatrix* lhs) {
+  const CompressedRowBlockStructure* bs = A.block_structure();
+  const double* values = A.values();
+
   const CompressedRow& row = bs->rows[row_block_index];
-  const double* values = A->values();
   for (int i = 1; i < row.cells.size(); ++i) {
     const int block1 = row.cells[i].block_id - num_eliminate_blocks_;
     DCHECK_GE(block1, 0);
 
     const int block1_size = bs->cols[row.cells[i].block_id].size;
     int r, c, row_stride, col_stride;
-    CellInfo* cell_info = lhs->GetCell(block1, block1,
-                                       &r, &c,
-                                       &row_stride, &col_stride);
+    CellInfo* cell_info =
+        lhs->GetCell(block1, block1, &r, &c, &row_stride, &col_stride);
     if (cell_info != NULL) {
       std::lock_guard<std::mutex> l(cell_info->m);
       // block += b1.transpose() * b1;
+      // clang-format off
       MatrixTransposeMatrixMultiply
           <kRowBlockSize, kFBlockSize, kRowBlockSize, kFBlockSize, 1>(
           values + row.cells[i].position, row.block.size, block1_size,
           values + row.cells[i].position, row.block.size, block1_size,
           cell_info->values, r, c, row_stride, col_stride);
+      // clang-format on
     }
 
     for (int j = i + 1; j < row.cells.size(); ++j) {
@@ -684,17 +700,18 @@
       DCHECK_LT(block1, block2);
       const int block2_size = bs->cols[row.cells[j].block_id].size;
       int r, c, row_stride, col_stride;
-      CellInfo* cell_info = lhs->GetCell(block1, block2,
-                                         &r, &c,
-                                         &row_stride, &col_stride);
+      CellInfo* cell_info =
+          lhs->GetCell(block1, block2, &r, &c, &row_stride, &col_stride);
       if (cell_info != NULL) {
         // block += b1.transpose() * b2;
         std::lock_guard<std::mutex> l(cell_info->m);
+        // clang-format off
         MatrixTransposeMatrixMultiply
             <kRowBlockSize, kFBlockSize, kRowBlockSize, kFBlockSize, 1>(
                 values + row.cells[i].position, row.block.size, block1_size,
                 values + row.cells[j].position, row.block.size, block2_size,
                 cell_info->values, r, c, row_stride, col_stride);
+        // clang-format on
       }
     }
   }
diff --git a/internal/ceres/schur_eliminator_template.py b/internal/ceres/schur_eliminator_template.py
index 2f38cf5..5051595 100644
--- a/internal/ceres/schur_eliminator_template.py
+++ b/internal/ceres/schur_eliminator_template.py
@@ -93,9 +93,7 @@
 """
 
 DYNAMIC_FILE = """
-
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
@@ -113,7 +111,6 @@
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 
 #include "ceres/schur_eliminator_impl.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
@@ -129,25 +126,24 @@
 FACTORY_FILE_HEADER = """
 #include "ceres/linear_solver.h"
 #include "ceres/schur_eliminator.h"
-#include "ceres/internal/eigen.h"
 
 namespace ceres {
 namespace internal {
 
-SchurEliminatorBase*
-SchurEliminatorBase::Create(const LinearSolver::Options& options) {
+SchurEliminatorBase* SchurEliminatorBase::Create(
+    const LinearSolver::Options& options) {
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
 """
 
-FACTORY = """ return new SchurEliminator<%s, %s, %s>(options);"""
+FACTORY = """  return new SchurEliminator<%s, %s, %s>(options);"""
 
 FACTORY_FOOTER = """
 #endif
   VLOG(1) << "Template specializations not found for <"
-          << options.row_block_size << ","
-          << options.e_block_size << ","
+          << options.row_block_size << "," << options.e_block_size << ","
           << options.f_block_size << ">";
-  return new SchurEliminator<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>(options);
+  return new SchurEliminator<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>(
+      options);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/schur_eliminator_test.cc b/internal/ceres/schur_eliminator_test.cc
index 2e8492f..6383ced 100644
--- a/internal/ceres/schur_eliminator_test.cc
+++ b/internal/ceres/schur_eliminator_test.cc
@@ -1,5 +1,5 @@
 // Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2015 Google Inc. All rights reserved.
+// Copyright 2019 Google Inc. All rights reserved.
 // http://ceres-solver.org/
 //
 // Redistribution and use in source and binary forms, with or without
@@ -31,14 +31,17 @@
 #include "ceres/schur_eliminator.h"
 
 #include <memory>
+
 #include "Eigen/Dense"
 #include "ceres/block_random_access_dense_matrix.h"
 #include "ceres/block_sparse_matrix.h"
+#include "ceres/block_structure.h"
 #include "ceres/casts.h"
 #include "ceres/context_impl.h"
 #include "ceres/detect_structure.h"
 #include "ceres/internal/eigen.h"
 #include "ceres/linear_least_squares_problems.h"
+#include "ceres/random.h"
 #include "ceres/test_util.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "ceres/types.h"
@@ -54,8 +57,8 @@
 class SchurEliminatorTest : public ::testing::Test {
  protected:
   void SetUpFromId(int id) {
-    std::unique_ptr<LinearLeastSquaresProblem>
-        problem(CreateLinearLeastSquaresProblemFromId(id));
+    std::unique_ptr<LinearLeastSquaresProblem> problem(
+        CreateLinearLeastSquaresProblemFromId(id));
     CHECK(problem != nullptr);
     SetupHelper(problem.get());
   }
@@ -82,7 +85,7 @@
     A->ToDenseMatrix(&J);
     VectorRef f(b.get(), J.rows());
 
-    Matrix H  =  (D.cwiseProduct(D)).asDiagonal();
+    Matrix H = (D.cwiseProduct(D)).asDiagonal();
     H.noalias() += J.transpose() * J;
 
     const Vector g = J.transpose() * f;
@@ -98,28 +101,21 @@
     sol_expected.setZero();
 
     Matrix P = H.block(0, 0, num_eliminate_cols, num_eliminate_cols);
-    Matrix Q = H.block(0,
-                       num_eliminate_cols,
-                       num_eliminate_cols,
-                       schur_size);
-    Matrix R = H.block(num_eliminate_cols,
-                       num_eliminate_cols,
-                       schur_size,
-                       schur_size);
+    Matrix Q = H.block(0, num_eliminate_cols, num_eliminate_cols, schur_size);
+    Matrix R =
+        H.block(num_eliminate_cols, num_eliminate_cols, schur_size, schur_size);
     int row = 0;
     const CompressedRowBlockStructure* bs = A->block_structure();
     for (int i = 0; i < num_eliminate_blocks; ++i) {
-      const int block_size =  bs->cols[i].size;
-      P.block(row, row,  block_size, block_size) =
-          P
-          .block(row, row,  block_size, block_size)
-          .llt()
-          .solve(Matrix::Identity(block_size, block_size));
+      const int block_size = bs->cols[i].size;
+      P.block(row, row, block_size, block_size) =
+          P.block(row, row, block_size, block_size)
+              .llt()
+              .solve(Matrix::Identity(block_size, block_size));
       row += block_size;
     }
 
-    lhs_expected
-        .triangularView<Eigen::Upper>() = R - Q.transpose() * P * Q;
+    lhs_expected.triangularView<Eigen::Upper>() = R - Q.transpose() * P * Q;
     rhs_expected =
         g.tail(schur_size) - Q.transpose() * P * g.head(num_eliminate_cols);
     sol_expected = H.llt().solve(g);
@@ -158,20 +154,18 @@
     eliminator.reset(SchurEliminatorBase::Create(options));
     const bool kFullRankETE = true;
     eliminator->Init(num_eliminate_blocks, kFullRankETE, A->block_structure());
-    eliminator->Eliminate(A.get(), b.get(), diagonal.data(), &lhs, rhs.data());
+    eliminator->Eliminate(
+        BlockSparseMatrixData(*A), b.get(), diagonal.data(), &lhs, rhs.data());
 
     MatrixRef lhs_ref(lhs.mutable_values(), lhs.num_rows(), lhs.num_cols());
-    Vector reduced_sol  =
-        lhs_ref
-        .selfadjointView<Eigen::Upper>()
-        .llt()
-        .solve(rhs);
+    Vector reduced_sol =
+        lhs_ref.selfadjointView<Eigen::Upper>().llt().solve(rhs);
 
     // Solution to the linear least squares problem.
     Vector sol(num_cols);
     sol.setZero();
     sol.tail(schur_size) = reduced_sol;
-    eliminator->BackSubstitute(A.get(),
+    eliminator->BackSubstitute(BlockSparseMatrixData(*A),
                                b.get(),
                                diagonal.data(),
                                reduced_sol.data(),
@@ -180,9 +174,11 @@
     Matrix delta = (lhs_ref - lhs_expected).selfadjointView<Eigen::Upper>();
     double diff = delta.norm();
     EXPECT_NEAR(diff / lhs_expected.norm(), 0.0, relative_tolerance);
-    EXPECT_NEAR((rhs - rhs_expected).norm() / rhs_expected.norm(), 0.0,
+    EXPECT_NEAR((rhs - rhs_expected).norm() / rhs_expected.norm(),
+                0.0,
                 relative_tolerance);
-    EXPECT_NEAR((sol - sol_expected).norm() / sol_expected.norm(), 0.0,
+    EXPECT_NEAR((sol - sol_expected).norm() / sol_expected.norm(),
+                0.0,
                 relative_tolerance);
   }
 
@@ -226,5 +222,152 @@
   EliminateSolveAndCompare(VectorRef(D.get(), A->num_cols()), false, 1e-14);
 }
 
+TEST(SchurEliminatorForOneFBlock, MatchesSchurEliminator) {
+  constexpr int kRowBlockSize = 2;
+  constexpr int kEBlockSize = 3;
+  constexpr int kFBlockSize = 6;
+  constexpr int num_e_blocks = 5;
+
+  CompressedRowBlockStructure* bs = new CompressedRowBlockStructure;
+  bs->cols.resize(num_e_blocks + 1);
+  int col_pos = 0;
+  for (int i = 0; i < num_e_blocks; ++i) {
+    bs->cols[i].position = col_pos;
+    bs->cols[i].size = kEBlockSize;
+    col_pos += kEBlockSize;
+  }
+  bs->cols.back().position = col_pos;
+  bs->cols.back().size = kFBlockSize;
+
+  bs->rows.resize(2 * num_e_blocks + 1);
+  int row_pos = 0;
+  int cell_pos = 0;
+  for (int i = 0; i < num_e_blocks; ++i) {
+    {
+      auto& row = bs->rows[2 * i];
+      row.block.position = row_pos;
+      row.block.size = kRowBlockSize;
+      row_pos += kRowBlockSize;
+      auto& cells = row.cells;
+      cells.resize(2);
+      cells[0].block_id = i;
+      cells[0].position = cell_pos;
+      cell_pos += kRowBlockSize * kEBlockSize;
+      cells[1].block_id = num_e_blocks;
+      cells[1].position = cell_pos;
+      cell_pos += kRowBlockSize * kFBlockSize;
+    }
+    {
+      auto& row = bs->rows[2 * i + 1];
+      row.block.position = row_pos;
+      row.block.size = kRowBlockSize;
+      row_pos += kRowBlockSize;
+      auto& cells = row.cells;
+      cells.resize(1);
+      cells[0].block_id = i;
+      cells[0].position = cell_pos;
+      cell_pos += kRowBlockSize * kEBlockSize;
+    }
+  }
+
+  {
+    auto& row = bs->rows.back();
+    row.block.position = row_pos;
+    row.block.size = kEBlockSize;
+    row_pos += kRowBlockSize;
+    auto& cells = row.cells;
+    cells.resize(1);
+    cells[0].block_id = num_e_blocks;
+    cells[0].position = cell_pos;
+    cell_pos += kEBlockSize * kEBlockSize;
+  }
+
+  BlockSparseMatrix matrix(bs);
+  double* values = matrix.mutable_values();
+  for (int i = 0; i < matrix.num_nonzeros(); ++i) {
+    values[i] = RandNormal();
+  }
+
+  Vector b(matrix.num_rows());
+  b.setRandom();
+
+  Vector diagonal(matrix.num_cols());
+  diagonal.setOnes();
+
+  std::vector<int> blocks(1, kFBlockSize);
+  BlockRandomAccessDenseMatrix actual_lhs(blocks);
+  BlockRandomAccessDenseMatrix expected_lhs(blocks);
+  Vector actual_rhs(kFBlockSize);
+  Vector expected_rhs(kFBlockSize);
+
+  Vector f_sol(kFBlockSize);
+  f_sol.setRandom();
+  Vector actual_e_sol(num_e_blocks * kEBlockSize);
+  actual_e_sol.setZero();
+  Vector expected_e_sol(num_e_blocks * kEBlockSize);
+  expected_e_sol.setZero();
+
+  {
+    ContextImpl context;
+    LinearSolver::Options linear_solver_options;
+    linear_solver_options.e_block_size = kEBlockSize;
+    linear_solver_options.row_block_size = kRowBlockSize;
+    linear_solver_options.f_block_size = kFBlockSize;
+    linear_solver_options.context = &context;
+    std::unique_ptr<SchurEliminatorBase> eliminator(
+        SchurEliminatorBase::Create(linear_solver_options));
+    eliminator->Init(num_e_blocks, true, matrix.block_structure());
+    eliminator->Eliminate(BlockSparseMatrixData(matrix),
+                          b.data(),
+                          diagonal.data(),
+                          &expected_lhs,
+                          expected_rhs.data());
+    eliminator->BackSubstitute(BlockSparseMatrixData(matrix),
+                               b.data(),
+                               diagonal.data(),
+                               f_sol.data(),
+                               actual_e_sol.data());
+  }
+
+  {
+    SchurEliminatorForOneFBlock<2, 3, 6> eliminator;
+    eliminator.Init(num_e_blocks, true, matrix.block_structure());
+    eliminator.Eliminate(BlockSparseMatrixData(matrix),
+                         b.data(),
+                         diagonal.data(),
+                         &actual_lhs,
+                         actual_rhs.data());
+    eliminator.BackSubstitute(BlockSparseMatrixData(matrix),
+                              b.data(),
+                              diagonal.data(),
+                              f_sol.data(),
+                              expected_e_sol.data());
+  }
+  ConstMatrixRef actual_lhsref(
+      actual_lhs.values(), actual_lhs.num_cols(), actual_lhs.num_cols());
+  ConstMatrixRef expected_lhsref(
+      expected_lhs.values(), actual_lhs.num_cols(), actual_lhs.num_cols());
+
+  EXPECT_NEAR((actual_lhsref - expected_lhsref).norm() / expected_lhsref.norm(),
+              0.0,
+              1e-12)
+      << "expected: \n"
+      << expected_lhsref << "\nactual: \n"
+      << actual_lhsref;
+
+  EXPECT_NEAR(
+      (actual_rhs - expected_rhs).norm() / expected_rhs.norm(), 0.0, 1e-12)
+      << "expected: \n"
+      << expected_rhs << "\nactual: \n"
+      << actual_rhs;
+
+  EXPECT_NEAR((actual_e_sol - expected_e_sol).norm() / expected_e_sol.norm(),
+              0.0,
+              1e-12)
+      << "expected: \n"
+      << expected_e_sol << "\nactual: \n"
+      << actual_e_sol;
+}
+
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/schur_jacobi_preconditioner.cc b/internal/ceres/schur_jacobi_preconditioner.cc
index 1500650..89d770b 100644
--- a/internal/ceres/schur_jacobi_preconditioner.cc
+++ b/internal/ceres/schur_jacobi_preconditioner.cc
@@ -49,9 +49,8 @@
   CHECK_GT(options_.elimination_groups.size(), 1);
   CHECK_GT(options_.elimination_groups[0], 0);
   const int num_blocks = bs.cols.size() - options_.elimination_groups[0];
-  CHECK_GT(num_blocks, 0)
-      << "Jacobian should have at least 1 f_block for "
-      << "SCHUR_JACOBI preconditioner.";
+  CHECK_GT(num_blocks, 0) << "Jacobian should have at least 1 f_block for "
+                          << "SCHUR_JACOBI preconditioner.";
   CHECK(options_.context != NULL);
 
   std::vector<int> blocks(num_blocks);
@@ -63,8 +62,7 @@
   InitEliminator(bs);
 }
 
-SchurJacobiPreconditioner::~SchurJacobiPreconditioner() {
-}
+SchurJacobiPreconditioner::~SchurJacobiPreconditioner() {}
 
 // Initialize the SchurEliminator.
 void SchurJacobiPreconditioner::InitEliminator(
@@ -89,7 +87,8 @@
   CHECK_GT(num_rows, 0);
 
   // Compute a subset of the entries of the Schur complement.
-  eliminator_->Eliminate(&A, nullptr, D, m_.get(), nullptr);
+  eliminator_->Eliminate(
+      BlockSparseMatrixData(A), nullptr, D, m_.get(), nullptr);
   m_->Invert();
   return true;
 }
@@ -99,9 +98,7 @@
   m_->RightMultiply(x, y);
 }
 
-int SchurJacobiPreconditioner::num_rows() const {
-  return m_->num_rows();
-}
+int SchurJacobiPreconditioner::num_rows() const { return m_->num_rows(); }
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/schur_jacobi_preconditioner.h b/internal/ceres/schur_jacobi_preconditioner.h
index c95468f..372b790 100644
--- a/internal/ceres/schur_jacobi_preconditioner.h
+++ b/internal/ceres/schur_jacobi_preconditioner.h
@@ -88,12 +88,12 @@
   virtual ~SchurJacobiPreconditioner();
 
   // Preconditioner interface.
-  virtual void RightMultiply(const double* x, double* y) const;
-  virtual int num_rows() const;
+  void RightMultiply(const double* x, double* y) const final;
+  int num_rows() const final;
 
  private:
   void InitEliminator(const CompressedRowBlockStructure& bs);
-  virtual bool UpdateImpl(const BlockSparseMatrix& A, const double* D);
+  bool UpdateImpl(const BlockSparseMatrix& A, const double* D) final;
 
   Preconditioner::Options options_;
   std::unique_ptr<SchurEliminatorBase> eliminator_;
diff --git a/internal/ceres/schur_templates.cc b/internal/ceres/schur_templates.cc
index 64bc9f3..bcf0d14 100644
--- a/internal/ceres/schur_templates.cc
+++ b/internal/ceres/schur_templates.cc
@@ -56,160 +56,168 @@
   *e_block_size = Eigen::Dynamic;
   *f_block_size = Eigen::Dynamic;
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
- if ((options.row_block_size == 2) &&
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 2) &&
      (options.f_block_size == 2)) {
-   *row_block_size = 2;
-   *e_block_size = 2;
-   *f_block_size = 2;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 2;
+    *f_block_size = 2;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 2) &&
      (options.f_block_size == 3)) {
-   *row_block_size = 2;
-   *e_block_size = 2;
-   *f_block_size = 3;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 2;
+    *f_block_size = 3;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 2) &&
      (options.f_block_size == 4)) {
-   *row_block_size = 2;
-   *e_block_size = 2;
-   *f_block_size = 4;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 2;
+    *f_block_size = 4;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 2)) {
-   *row_block_size = 2;
-   *e_block_size = 2;
-   *f_block_size = Eigen::Dynamic;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 2;
+    *f_block_size = Eigen::Dynamic;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3) &&
      (options.f_block_size == 3)) {
-   *row_block_size = 2;
-   *e_block_size = 3;
-   *f_block_size = 3;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 3;
+    *f_block_size = 3;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3) &&
      (options.f_block_size == 4)) {
-   *row_block_size = 2;
-   *e_block_size = 3;
-   *f_block_size = 4;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 3;
+    *f_block_size = 4;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3) &&
      (options.f_block_size == 6)) {
-   *row_block_size = 2;
-   *e_block_size = 3;
-   *f_block_size = 6;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 3;
+    *f_block_size = 6;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3) &&
      (options.f_block_size == 9)) {
-   *row_block_size = 2;
-   *e_block_size = 3;
-   *f_block_size = 9;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 3;
+    *f_block_size = 9;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 3)) {
-   *row_block_size = 2;
-   *e_block_size = 3;
-   *f_block_size = Eigen::Dynamic;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 3;
+    *f_block_size = Eigen::Dynamic;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 3)) {
-   *row_block_size = 2;
-   *e_block_size = 4;
-   *f_block_size = 3;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 4;
+    *f_block_size = 3;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 4)) {
-   *row_block_size = 2;
-   *e_block_size = 4;
-   *f_block_size = 4;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 4;
+    *f_block_size = 4;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 6)) {
-   *row_block_size = 2;
-   *e_block_size = 4;
-   *f_block_size = 6;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 4;
+    *f_block_size = 6;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 8)) {
-   *row_block_size = 2;
-   *e_block_size = 4;
-   *f_block_size = 8;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 4;
+    *f_block_size = 8;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 9)) {
-   *row_block_size = 2;
-   *e_block_size = 4;
-   *f_block_size = 9;
-  return;
- }
- if ((options.row_block_size == 2) &&
+    *row_block_size = 2;
+    *e_block_size = 4;
+    *f_block_size = 9;
+    return;
+  }
+  if ((options.row_block_size == 2) &&
      (options.e_block_size == 4)) {
-   *row_block_size = 2;
-   *e_block_size = 4;
-   *f_block_size = Eigen::Dynamic;
-  return;
- }
- if (options.row_block_size == 2){
-   *row_block_size = 2;
-   *e_block_size = Eigen::Dynamic;
-   *f_block_size = Eigen::Dynamic;
-  return;
- }
- if ((options.row_block_size == 4) &&
+    *row_block_size = 2;
+    *e_block_size = 4;
+    *f_block_size = Eigen::Dynamic;
+    return;
+  }
+  if (options.row_block_size == 2) {
+    *row_block_size = 2;
+    *e_block_size = Eigen::Dynamic;
+    *f_block_size = Eigen::Dynamic;
+    return;
+  }
+  if ((options.row_block_size == 3) &&
+     (options.e_block_size == 3) &&
+     (options.f_block_size == 3)) {
+    *row_block_size = 3;
+    *e_block_size = 3;
+    *f_block_size = 3;
+    return;
+  }
+  if ((options.row_block_size == 4) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 2)) {
-   *row_block_size = 4;
-   *e_block_size = 4;
-   *f_block_size = 2;
-  return;
- }
- if ((options.row_block_size == 4) &&
+    *row_block_size = 4;
+    *e_block_size = 4;
+    *f_block_size = 2;
+    return;
+  }
+  if ((options.row_block_size == 4) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 3)) {
-   *row_block_size = 4;
-   *e_block_size = 4;
-   *f_block_size = 3;
-  return;
- }
- if ((options.row_block_size == 4) &&
+    *row_block_size = 4;
+    *e_block_size = 4;
+    *f_block_size = 3;
+    return;
+  }
+  if ((options.row_block_size == 4) &&
      (options.e_block_size == 4) &&
      (options.f_block_size == 4)) {
-   *row_block_size = 4;
-   *e_block_size = 4;
-   *f_block_size = 4;
-  return;
- }
- if ((options.row_block_size == 4) &&
+    *row_block_size = 4;
+    *e_block_size = 4;
+    *f_block_size = 4;
+    return;
+  }
+  if ((options.row_block_size == 4) &&
      (options.e_block_size == 4)) {
-   *row_block_size = 4;
-   *e_block_size = 4;
-   *f_block_size = Eigen::Dynamic;
-  return;
- }
+    *row_block_size = 4;
+    *e_block_size = 4;
+    *f_block_size = Eigen::Dynamic;
+    return;
+  }
 
 #endif
   return;
diff --git a/internal/ceres/scratch_evaluate_preparer.cc b/internal/ceres/scratch_evaluate_preparer.cc
index f01ef11..9905b22 100644
--- a/internal/ceres/scratch_evaluate_preparer.cc
+++ b/internal/ceres/scratch_evaluate_preparer.cc
@@ -37,9 +37,8 @@
 namespace ceres {
 namespace internal {
 
-ScratchEvaluatePreparer* ScratchEvaluatePreparer::Create(
-    const Program &program,
-    int num_threads) {
+ScratchEvaluatePreparer* ScratchEvaluatePreparer::Create(const Program& program,
+                                                         int num_threads) {
   ScratchEvaluatePreparer* preparers = new ScratchEvaluatePreparer[num_threads];
   int max_derivatives_per_residual_block =
       program.MaxDerivativesPerResidualBlock();
@@ -50,8 +49,7 @@
 }
 
 void ScratchEvaluatePreparer::Init(int max_derivatives_per_residual_block) {
-  jacobian_scratch_.reset(
-      new double[max_derivatives_per_residual_block]);
+  jacobian_scratch_.reset(new double[max_derivatives_per_residual_block]);
 }
 
 // Point the jacobian blocks into the scratch area of this evaluate preparer.
diff --git a/internal/ceres/scratch_evaluate_preparer.h b/internal/ceres/scratch_evaluate_preparer.h
index c8d9b93..2d2745d 100644
--- a/internal/ceres/scratch_evaluate_preparer.h
+++ b/internal/ceres/scratch_evaluate_preparer.h
@@ -47,7 +47,7 @@
 class ScratchEvaluatePreparer {
  public:
   // Create num_threads ScratchEvaluatePreparers.
-  static ScratchEvaluatePreparer* Create(const Program &program,
+  static ScratchEvaluatePreparer* Create(const Program& program,
                                          int num_threads);
 
   // EvaluatePreparer interface
diff --git a/internal/ceres/single_linkage_clustering.cc b/internal/ceres/single_linkage_clustering.cc
index 394492c..0e78131 100644
--- a/internal/ceres/single_linkage_clustering.cc
+++ b/internal/ceres/single_linkage_clustering.cc
@@ -30,8 +30,9 @@
 
 #include "ceres/single_linkage_clustering.h"
 
-#include <unordered_set>
 #include <unordered_map>
+#include <unordered_set>
+
 #include "ceres/graph.h"
 #include "ceres/graph_algorithms.h"
 
diff --git a/internal/ceres/single_linkage_clustering.h b/internal/ceres/single_linkage_clustering.h
index ccd6f8e..e891a9e 100644
--- a/internal/ceres/single_linkage_clustering.h
+++ b/internal/ceres/single_linkage_clustering.h
@@ -32,7 +32,9 @@
 #define CERES_INTERNAL_SINGLE_LINKAGE_CLUSTERING_H_
 
 #include <unordered_map>
+
 #include "ceres/graph.h"
+#include "ceres/internal/port.h"
 
 namespace ceres {
 namespace internal {
@@ -53,10 +55,10 @@
 //
 // The return value of this function is the number of clusters
 // identified by the algorithm.
-int ComputeSingleLinkageClustering(
-    const SingleLinkageClusteringOptions& options,
-    const WeightedGraph<int>& graph,
-    std::unordered_map<int, int>* membership);
+int CERES_EXPORT_INTERNAL
+ComputeSingleLinkageClustering(const SingleLinkageClusteringOptions& options,
+                               const WeightedGraph<int>& graph,
+                               std::unordered_map<int, int>* membership);
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/single_linkage_clustering_test.cc b/internal/ceres/single_linkage_clustering_test.cc
index 281c281..28c7c41 100644
--- a/internal/ceres/single_linkage_clustering_test.cc
+++ b/internal/ceres/single_linkage_clustering_test.cc
@@ -31,6 +31,7 @@
 #include "ceres/single_linkage_clustering.h"
 
 #include <unordered_map>
+
 #include "ceres/graph.h"
 #include "gtest/gtest.h"
 
diff --git a/internal/ceres/small_blas.h b/internal/ceres/small_blas.h
index 81c5872..4ee9229 100644
--- a/internal/ceres/small_blas.h
+++ b/internal/ceres/small_blas.h
@@ -35,8 +35,8 @@
 #ifndef CERES_INTERNAL_SMALL_BLAS_H_
 #define CERES_INTERNAL_SMALL_BLAS_H_
 
-#include "ceres/internal/port.h"
 #include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
 #include "glog/logging.h"
 #include "small_blas_generic.h"
 
@@ -46,7 +46,7 @@
 // The following three macros are used to share code and reduce
 // template junk across the various GEMM variants.
 #define CERES_GEMM_BEGIN(name)                                          \
-  template<int kRowA, int kColA, int kRowB, int kColB, int kOperation>  \
+  template <int kRowA, int kColA, int kRowB, int kColB, int kOperation> \
   inline void name(const double* A,                                     \
                    const int num_row_a,                                 \
                    const int num_col_a,                                 \
@@ -59,56 +59,58 @@
                    const int row_stride_c,                              \
                    const int col_stride_c)
 
-#define CERES_GEMM_NAIVE_HEADER                                         \
-  DCHECK_GT(num_row_a, 0);                                              \
-  DCHECK_GT(num_col_a, 0);                                              \
-  DCHECK_GT(num_row_b, 0);                                              \
-  DCHECK_GT(num_col_b, 0);                                              \
-  DCHECK_GE(start_row_c, 0);                                            \
-  DCHECK_GE(start_col_c, 0);                                            \
-  DCHECK_GT(row_stride_c, 0);                                           \
-  DCHECK_GT(col_stride_c, 0);                                           \
-  DCHECK((kRowA == Eigen::Dynamic) || (kRowA == num_row_a));            \
-  DCHECK((kColA == Eigen::Dynamic) || (kColA == num_col_a));            \
-  DCHECK((kRowB == Eigen::Dynamic) || (kRowB == num_row_b));            \
-  DCHECK((kColB == Eigen::Dynamic) || (kColB == num_col_b));            \
-  const int NUM_ROW_A = (kRowA != Eigen::Dynamic ? kRowA : num_row_a);  \
-  const int NUM_COL_A = (kColA != Eigen::Dynamic ? kColA : num_col_a);  \
-  const int NUM_ROW_B = (kRowB != Eigen::Dynamic ? kRowB : num_row_b);  \
+#define CERES_GEMM_NAIVE_HEADER                                        \
+  DCHECK_GT(num_row_a, 0);                                             \
+  DCHECK_GT(num_col_a, 0);                                             \
+  DCHECK_GT(num_row_b, 0);                                             \
+  DCHECK_GT(num_col_b, 0);                                             \
+  DCHECK_GE(start_row_c, 0);                                           \
+  DCHECK_GE(start_col_c, 0);                                           \
+  DCHECK_GT(row_stride_c, 0);                                          \
+  DCHECK_GT(col_stride_c, 0);                                          \
+  DCHECK((kRowA == Eigen::Dynamic) || (kRowA == num_row_a));           \
+  DCHECK((kColA == Eigen::Dynamic) || (kColA == num_col_a));           \
+  DCHECK((kRowB == Eigen::Dynamic) || (kRowB == num_row_b));           \
+  DCHECK((kColB == Eigen::Dynamic) || (kColB == num_col_b));           \
+  const int NUM_ROW_A = (kRowA != Eigen::Dynamic ? kRowA : num_row_a); \
+  const int NUM_COL_A = (kColA != Eigen::Dynamic ? kColA : num_col_a); \
+  const int NUM_ROW_B = (kRowB != Eigen::Dynamic ? kRowB : num_row_b); \
   const int NUM_COL_B = (kColB != Eigen::Dynamic ? kColB : num_col_b);
 
-#define CERES_GEMM_EIGEN_HEADER                                         \
-  const typename EigenTypes<kRowA, kColA>::ConstMatrixRef               \
-  Aref(A, num_row_a, num_col_a);                                        \
-  const typename EigenTypes<kRowB, kColB>::ConstMatrixRef               \
-  Bref(B, num_row_b, num_col_b);                                        \
-  MatrixRef Cref(C, row_stride_c, col_stride_c);                        \
+#define CERES_GEMM_EIGEN_HEADER                                 \
+  const typename EigenTypes<kRowA, kColA>::ConstMatrixRef Aref( \
+      A, num_row_a, num_col_a);                                 \
+  const typename EigenTypes<kRowB, kColB>::ConstMatrixRef Bref( \
+      B, num_row_b, num_col_b);                                 \
+  MatrixRef Cref(C, row_stride_c, col_stride_c);
 
+// clang-format off
 #define CERES_CALL_GEMM(name)                                           \
   name<kRowA, kColA, kRowB, kColB, kOperation>(                         \
       A, num_row_a, num_col_a,                                          \
       B, num_row_b, num_col_b,                                          \
       C, start_row_c, start_col_c, row_stride_c, col_stride_c);
+// clang-format on
 
-#define CERES_GEMM_STORE_SINGLE(p, index, value)                        \
-  if (kOperation > 0) {                                                 \
-    p[index] += value;                                                  \
-  } else if (kOperation < 0) {                                          \
-    p[index] -= value;                                                  \
-  } else {                                                              \
-    p[index] = value;                                                   \
+#define CERES_GEMM_STORE_SINGLE(p, index, value) \
+  if (kOperation > 0) {                          \
+    p[index] += value;                           \
+  } else if (kOperation < 0) {                   \
+    p[index] -= value;                           \
+  } else {                                       \
+    p[index] = value;                            \
   }
 
-#define CERES_GEMM_STORE_PAIR(p, index, v1, v2)                         \
-  if (kOperation > 0) {                                                 \
-    p[index] += v1;                                                     \
-    p[index + 1] += v2;                                                 \
-  } else if (kOperation < 0) {                                          \
-    p[index] -= v1;                                                     \
-    p[index + 1] -= v2;                                                 \
-  } else {                                                              \
-    p[index] = v1;                                                      \
-    p[index + 1] = v2;                                                  \
+#define CERES_GEMM_STORE_PAIR(p, index, v1, v2) \
+  if (kOperation > 0) {                         \
+    p[index] += v1;                             \
+    p[index + 1] += v2;                         \
+  } else if (kOperation < 0) {                  \
+    p[index] -= v1;                             \
+    p[index + 1] -= v2;                         \
+  } else {                                      \
+    p[index] = v1;                              \
+    p[index + 1] = v2;                          \
   }
 
 // For the matrix-matrix functions below, there are three variants for
@@ -161,8 +163,8 @@
 //
 CERES_GEMM_BEGIN(MatrixMatrixMultiplyEigen) {
   CERES_GEMM_EIGEN_HEADER
-  Eigen::Block<MatrixRef, kRowA, kColB>
-    block(Cref, start_row_c, start_col_c, num_row_a, num_col_b);
+  Eigen::Block<MatrixRef, kRowA, kColB> block(
+      Cref, start_row_c, start_col_c, num_row_a, num_col_b);
 
   if (kOperation > 0) {
     block.noalias() += Aref * Bref;
@@ -208,7 +210,7 @@
 
   // Process the couple columns in remainder if present.
   if (NUM_COL_C & 2) {
-    int col = NUM_COL_C & (int)(~(span - 1)) ;
+    int col = NUM_COL_C & (int)(~(span - 1));
     const double* pa = &A[0];
     for (int row = 0; row < NUM_ROW_C; ++row, pa += NUM_COL_A) {
       const double* pb = &B[col];
@@ -234,11 +236,12 @@
   for (int col = 0; col < col_m; col += span) {
     for (int row = 0; row < NUM_ROW_C; ++row) {
       const int index = (row + start_row_c) * col_stride_c + start_col_c + col;
+      // clang-format off
       MMM_mat1x4(NUM_COL_A, &A[row * NUM_COL_A],
                  &B[col], NUM_COL_B, &C[index], kOperation);
+      // clang-format on
     }
   }
-
 }
 
 CERES_GEMM_BEGIN(MatrixMatrixMultiply) {
@@ -261,9 +264,11 @@
 
 CERES_GEMM_BEGIN(MatrixTransposeMatrixMultiplyEigen) {
   CERES_GEMM_EIGEN_HEADER
+  // clang-format off
   Eigen::Block<MatrixRef, kColA, kColB> block(Cref,
                                               start_row_c, start_col_c,
                                               num_col_a, num_col_b);
+  // clang-format on
   if (kOperation > 0) {
     block.noalias() += Aref.transpose() * Bref;
   } else if (kOperation < 0) {
@@ -310,7 +315,7 @@
 
   // Process the couple columns in remainder if present.
   if (NUM_COL_C & 2) {
-    int col = NUM_COL_C & (int)(~(span - 1)) ;
+    int col = NUM_COL_C & (int)(~(span - 1));
     for (int row = 0; row < NUM_ROW_C; ++row) {
       const double* pa = &A[row];
       const double* pb = &B[col];
@@ -338,11 +343,12 @@
   for (int col = 0; col < col_m; col += span) {
     for (int row = 0; row < NUM_ROW_C; ++row) {
       const int index = (row + start_row_c) * col_stride_c + start_col_c + col;
+      // clang-format off
       MTM_mat1x4(NUM_ROW_A, &A[row], NUM_COL_A,
                  &B[col], NUM_COL_B, &C[index], kOperation);
+      // clang-format on
     }
   }
-
 }
 
 CERES_GEMM_BEGIN(MatrixTransposeMatrixMultiply) {
@@ -376,15 +382,15 @@
 // kOperation =  1  -> c += A' * b
 // kOperation = -1  -> c -= A' * b
 // kOperation =  0  -> c  = A' * b
-template<int kRowA, int kColA, int kOperation>
+template <int kRowA, int kColA, int kOperation>
 inline void MatrixVectorMultiply(const double* A,
                                  const int num_row_a,
                                  const int num_col_a,
                                  const double* b,
                                  double* c) {
 #ifdef CERES_NO_CUSTOM_BLAS
-  const typename EigenTypes<kRowA, kColA>::ConstMatrixRef
-      Aref(A, num_row_a, num_col_a);
+  const typename EigenTypes<kRowA, kColA>::ConstMatrixRef Aref(
+      A, num_row_a, num_col_a);
   const typename EigenTypes<kColA>::ConstVectorRef bref(b, num_col_a);
   typename EigenTypes<kRowA>::VectorRef cref(c, num_row_a);
 
@@ -412,7 +418,7 @@
 
   // Process the last odd row if present.
   if (NUM_ROW_A & 1) {
-    int row  = NUM_ROW_A - 1;
+    int row = NUM_ROW_A - 1;
     const double* pa = &A[row * NUM_COL_A];
     const double* pb = &b[0];
     double tmp = 0.0;
@@ -450,8 +456,10 @@
   // Calculate the main part with multiples of 4.
   int row_m = NUM_ROW_A & (int)(~(span - 1));
   for (int row = 0; row < row_m; row += span) {
+    // clang-format off
     MVM_mat4x1(NUM_COL_A, &A[row * NUM_COL_A], NUM_COL_A,
                &b[0], &c[row], kOperation);
+    // clang-format on
   }
 
 #endif  // CERES_NO_CUSTOM_BLAS
@@ -460,15 +468,15 @@
 // Similar to MatrixVectorMultiply, except that A is transposed, i.e.,
 //
 // c op A' * b;
-template<int kRowA, int kColA, int kOperation>
+template <int kRowA, int kColA, int kOperation>
 inline void MatrixTransposeVectorMultiply(const double* A,
                                           const int num_row_a,
                                           const int num_col_a,
                                           const double* b,
                                           double* c) {
 #ifdef CERES_NO_CUSTOM_BLAS
-  const typename EigenTypes<kRowA, kColA>::ConstMatrixRef
-      Aref(A, num_row_a, num_col_a);
+  const typename EigenTypes<kRowA, kColA>::ConstMatrixRef Aref(
+      A, num_row_a, num_col_a);
   const typename EigenTypes<kRowA>::ConstVectorRef bref(b, num_row_a);
   typename EigenTypes<kColA>::VectorRef cref(c, num_col_a);
 
@@ -496,7 +504,7 @@
 
   // Process the last odd column if present.
   if (NUM_COL_A & 1) {
-    int row  = NUM_COL_A - 1;
+    int row = NUM_COL_A - 1;
     const double* pa = &A[row];
     const double* pb = &b[0];
     double tmp = 0.0;
@@ -519,10 +527,12 @@
     const double* pb = &b[0];
     double tmp1 = 0.0, tmp2 = 0.0;
     for (int col = 0; col < NUM_ROW_A; ++col) {
+      // clang-format off
       double bv = *pb++;
       tmp1 += *(pa    ) * bv;
       tmp2 += *(pa + 1) * bv;
       pa += NUM_COL_A;
+      // clang-format on
     }
     CERES_GEMM_STORE_PAIR(c, row, tmp1, tmp2);
 
@@ -535,8 +545,10 @@
   // Calculate the main part with multiples of 4.
   int row_m = NUM_COL_A & (int)(~(span - 1));
   for (int row = 0; row < row_m; row += span) {
+    // clang-format off
     MTV_mat4x1(NUM_ROW_A, &A[row], NUM_COL_A,
                &b[0], &c[row], kOperation);
+    // clang-format on
   }
 
 #endif  // CERES_NO_CUSTOM_BLAS
diff --git a/internal/ceres/small_blas_gemm_benchmark.cc b/internal/ceres/small_blas_gemm_benchmark.cc
index 0a760a5..aa6c41d 100644
--- a/internal/ceres/small_blas_gemm_benchmark.cc
+++ b/internal/ceres/small_blas_gemm_benchmark.cc
@@ -29,6 +29,7 @@
 // Authors: sameeragarwal@google.com (Sameer Agarwal)
 
 #include <iostream>
+
 #include "Eigen/Dense"
 #include "benchmark/benchmark.h"
 #include "ceres/small_blas.h"
@@ -103,11 +104,13 @@
   int iter = 0;
   for (auto _ : state) {
     // a += b * c
+    // clang-format off
     MatrixMatrixMultiply
         <Eigen::Dynamic, Eigen::Dynamic,Eigen::Dynamic,Eigen::Dynamic, 1>
         (data.GetB(iter), b_rows, b_cols,
          data.GetC(iter), c_rows, c_cols,
          data.GetA(iter), 0, 0, a_rows, a_cols);
+    // clang-format on
     iter = (iter + 1) % num_elements;
   }
 }
@@ -147,11 +150,13 @@
   int iter = 0;
   for (auto _ : state) {
     // a += b' * c
+    // clang-format off
     MatrixTransposeMatrixMultiply
         <Eigen::Dynamic,Eigen::Dynamic,Eigen::Dynamic,Eigen::Dynamic, 1>
         (data.GetB(iter), b_rows, b_cols,
          data.GetC(iter), c_rows, c_cols,
          data.GetA(iter), 0, 0, a_rows, a_cols);
+    // clang-format on
     iter = (iter + 1) % num_elements;
   }
 }
@@ -159,7 +164,7 @@
 BENCHMARK(BM_MatrixTransposeMatrixMultiplyDynamic)
     ->Apply(MatrixTransposeMatrixMultiplySizeArguments);
 
-}  // internal
+}  // namespace internal
 }  // namespace ceres
 
 BENCHMARK_MAIN();
diff --git a/internal/ceres/small_blas_generic.h b/internal/ceres/small_blas_generic.h
index 978c5d5..3f3ea42 100644
--- a/internal/ceres/small_blas_generic.h
+++ b/internal/ceres/small_blas_generic.h
@@ -39,33 +39,33 @@
 namespace internal {
 
 // The following macros are used to share code
-#define CERES_GEMM_OPT_NAIVE_HEADER              \
-  double c0 = 0.0;                               \
-  double c1 = 0.0;                               \
-  double c2 = 0.0;                               \
-  double c3 = 0.0;                               \
-  const double* pa = a;                          \
-  const double* pb = b;                          \
-  const int span = 4;                            \
-  int col_r = col_a & (span - 1);                \
+#define CERES_GEMM_OPT_NAIVE_HEADER \
+  double c0 = 0.0;                  \
+  double c1 = 0.0;                  \
+  double c2 = 0.0;                  \
+  double c3 = 0.0;                  \
+  const double* pa = a;             \
+  const double* pb = b;             \
+  const int span = 4;               \
+  int col_r = col_a & (span - 1);   \
   int col_m = col_a - col_r;
 
-#define CERES_GEMM_OPT_STORE_MAT1X4              \
-  if (kOperation > 0) {                          \
-    *c++ += c0;                                  \
-    *c++ += c1;                                  \
-    *c++ += c2;                                  \
-    *c++ += c3;                                  \
-  } else if (kOperation < 0) {                   \
-    *c++ -= c0;                                  \
-    *c++ -= c1;                                  \
-    *c++ -= c2;                                  \
-    *c++ -= c3;                                  \
-  } else {                                       \
-    *c++ = c0;                                   \
-    *c++ = c1;                                   \
-    *c++ = c2;                                   \
-    *c++ = c3;                                   \
+#define CERES_GEMM_OPT_STORE_MAT1X4 \
+  if (kOperation > 0) {             \
+    *c++ += c0;                     \
+    *c++ += c1;                     \
+    *c++ += c2;                     \
+    *c++ += c3;                     \
+  } else if (kOperation < 0) {      \
+    *c++ -= c0;                     \
+    *c++ -= c1;                     \
+    *c++ -= c2;                     \
+    *c++ -= c3;                     \
+  } else {                          \
+    *c++ = c0;                      \
+    *c++ = c1;                      \
+    *c++ = c2;                      \
+    *c++ = c3;                      \
   }
 
 // Matrix-Matrix Multiplication
@@ -97,14 +97,14 @@
   double av = 0.0;
   int bi = 0;
 
-#define CERES_GEMM_OPT_MMM_MAT1X4_MUL  \
-  av = pa[k];                          \
-  pb = b + bi;                         \
-  c0 += av * *pb++;                    \
-  c1 += av * *pb++;                    \
-  c2 += av * *pb++;                    \
-  c3 += av * *pb++;                    \
-  bi += col_stride_b;                  \
+#define CERES_GEMM_OPT_MMM_MAT1X4_MUL \
+  av = pa[k];                         \
+  pb = b + bi;                        \
+  c0 += av * *pb++;                   \
+  c1 += av * *pb++;                   \
+  c2 += av * *pb++;                   \
+  c3 += av * *pb++;                   \
+  bi += col_stride_b;                 \
   k++;
 
   for (int k = 0; k < col_m;) {
@@ -164,14 +164,14 @@
   int ai = 0;
   int bi = 0;
 
-#define CERES_GEMM_OPT_MTM_MAT1X4_MUL  \
-  av = pa[ai];                         \
-  pb = b + bi;                         \
-  c0 += av * *pb++;                    \
-  c1 += av * *pb++;                    \
-  c2 += av * *pb++;                    \
-  c3 += av * *pb++;                    \
-  ai += col_stride_a;                  \
+#define CERES_GEMM_OPT_MTM_MAT1X4_MUL \
+  av = pa[ai];                        \
+  pb = b + bi;                        \
+  c0 += av * *pb++;                   \
+  c1 += av * *pb++;                   \
+  c2 += av * *pb++;                   \
+  c3 += av * *pb++;                   \
+  ai += col_stride_a;                 \
   bi += col_stride_b;
 
   for (int k = 0; k < col_m; k += span) {
@@ -218,14 +218,16 @@
   CERES_GEMM_OPT_NAIVE_HEADER
   double bv = 0.0;
 
-#define CERES_GEMM_OPT_MVM_MAT4X1_MUL              \
-  bv = *pb;                                        \
-  c0 += *(pa                   ) * bv;             \
-  c1 += *(pa + col_stride_a    ) * bv;             \
-  c2 += *(pa + col_stride_a * 2) * bv;             \
-  c3 += *(pa + col_stride_a * 3) * bv;             \
-  pa++;                                            \
+  // clang-format off
+#define CERES_GEMM_OPT_MVM_MAT4X1_MUL  \
+  bv = *pb;                            \
+  c0 += *(pa                   ) * bv; \
+  c1 += *(pa + col_stride_a    ) * bv; \
+  c2 += *(pa + col_stride_a * 2) * bv; \
+  c3 += *(pa + col_stride_a * 3) * bv; \
+  pa++;                                \
   pb++;
+  // clang-format on
 
   for (int k = 0; k < col_m; k += span) {
     CERES_GEMM_OPT_MVM_MAT4X1_MUL
@@ -281,14 +283,16 @@
   CERES_GEMM_OPT_NAIVE_HEADER
   double bv = 0.0;
 
-#define CERES_GEMM_OPT_MTV_MAT4X1_MUL  \
-  bv = *pb;                            \
-  c0 += *(pa    ) * bv;                \
-  c1 += *(pa + 1) * bv;                \
-  c2 += *(pa + 2) * bv;                \
-  c3 += *(pa + 3) * bv;                \
-  pa += col_stride_a;                  \
+  // clang-format off
+#define CERES_GEMM_OPT_MTV_MAT4X1_MUL \
+  bv = *pb;                           \
+  c0 += *(pa    ) * bv;               \
+  c1 += *(pa + 1) * bv;               \
+  c2 += *(pa + 2) * bv;               \
+  c3 += *(pa + 3) * bv;               \
+  pa += col_stride_a;                 \
   pb++;
+  // clang-format on
 
   for (int k = 0; k < col_m; k += span) {
     CERES_GEMM_OPT_MTV_MAT4X1_MUL
diff --git a/internal/ceres/small_blas_test.cc b/internal/ceres/small_blas_test.cc
index 2914244..6f819c4 100644
--- a/internal/ceres/small_blas_test.cc
+++ b/internal/ceres/small_blas_test.cc
@@ -31,8 +31,9 @@
 #include "ceres/small_blas.h"
 
 #include <limits>
-#include "gtest/gtest.h"
+
 #include "ceres/internal/eigen.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
@@ -62,6 +63,7 @@
       Matrix C_plus_ref = C;
       Matrix C_minus_ref = C;
       Matrix C_assign_ref = C;
+      // clang-format off
       for (int start_row_c = 0; start_row_c + kRowA < row_stride_c; ++start_row_c) {
         for (int start_col_c = 0; start_col_c + kColB < col_stride_c; ++start_col_c) {
           C_plus_ref.block(start_row_c, start_col_c, kRowA, kColB) +=
@@ -81,7 +83,6 @@
               << "Cref : \n" << C_plus_ref << "\n"
               << "C: \n" << C_plus;
 
-
           C_minus_ref.block(start_row_c, start_col_c, kRowA, kColB) -=
               A * B;
 
@@ -117,6 +118,7 @@
               << "C: \n" << C_assign;
         }
       }
+      // clang-format on
     }
   }
 }
@@ -133,7 +135,7 @@
   B.setOnes();
 
   for (int row_stride_c = kColA; row_stride_c < 3 * kColA; ++row_stride_c) {
-    for (int col_stride_c = kColB; col_stride_c <  3 * kColB; ++col_stride_c) {
+    for (int col_stride_c = kColB; col_stride_c < 3 * kColB; ++col_stride_c) {
       Matrix C(row_stride_c, col_stride_c);
       C.setOnes();
 
@@ -144,6 +146,7 @@
       Matrix C_plus_ref = C;
       Matrix C_minus_ref = C;
       Matrix C_assign_ref = C;
+      // clang-format off
       for (int start_row_c = 0; start_row_c + kColA < row_stride_c; ++start_row_c) {
         for (int start_col_c = 0; start_col_c + kColB < col_stride_c; ++start_col_c) {
           C_plus_ref.block(start_row_c, start_col_c, kColA, kColB) +=
@@ -198,6 +201,7 @@
               << "C: \n" << C_assign;
         }
       }
+      // clang-format on
     }
   }
 }
@@ -228,6 +232,7 @@
       Matrix C_plus_ref = C;
       Matrix C_minus_ref = C;
       Matrix C_assign_ref = C;
+      // clang-format off
       for (int start_row_c = 0; start_row_c + kRowA < row_stride_c; ++start_row_c) {
         for (int start_col_c = 0; start_col_c + kColB < col_stride_c; ++start_col_c) {
           C_plus_ref.block(start_row_c, start_col_c, kRowA, kColB) +=
@@ -247,7 +252,6 @@
               << "Cref : \n" << C_plus_ref << "\n"
               << "C: \n" << C_plus;
 
-
           C_minus_ref.block(start_row_c, start_col_c, kRowA, kColB) -=
               A * B;
 
@@ -283,6 +287,7 @@
               << "C: \n" << C_assign;
         }
       }
+      // clang-format on
     }
   }
 }
@@ -299,7 +304,7 @@
   B.setOnes();
 
   for (int row_stride_c = kColA; row_stride_c < 3 * kColA; ++row_stride_c) {
-    for (int col_stride_c = kColB; col_stride_c <  3 * kColB; ++col_stride_c) {
+    for (int col_stride_c = kColB; col_stride_c < 3 * kColB; ++col_stride_c) {
       Matrix C(row_stride_c, col_stride_c);
       C.setOnes();
 
@@ -310,6 +315,7 @@
       Matrix C_plus_ref = C;
       Matrix C_minus_ref = C;
       Matrix C_assign_ref = C;
+      // clang-format off
       for (int start_row_c = 0; start_row_c + kColA < row_stride_c; ++start_row_c) {
         for (int start_col_c = 0; start_col_c + kColB < col_stride_c; ++start_col_c) {
           C_plus_ref.block(start_row_c, start_col_c, kColA, kColB) +=
@@ -364,6 +370,7 @@
               << "C: \n" << C_assign;
         }
       }
+      // clang-format on
     }
   }
 }
@@ -388,6 +395,7 @@
       Vector c_minus_ref = c;
       Vector c_assign_ref = c;
 
+      // clang-format off
       c_plus_ref += A * b;
       MatrixVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
           A.data(), num_rows_a, num_cols_a,
@@ -417,6 +425,7 @@
           << "c += A * b \n"
           << "c_ref : \n" << c_assign_ref << "\n"
           << "c: \n" << c_assign;
+      // clang-format on
     }
   }
 }
@@ -441,6 +450,7 @@
       Vector c_minus_ref = c;
       Vector c_assign_ref = c;
 
+      // clang-format off
       c_plus_ref += A.transpose() * b;
       MatrixTransposeVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
           A.data(), num_rows_a, num_cols_a,
@@ -470,6 +480,7 @@
           << "c += A' * b \n"
           << "c_ref : \n" << c_assign_ref << "\n"
           << "c: \n" << c_assign;
+      // clang-format on
     }
   }
 }
diff --git a/internal/ceres/solver.cc b/internal/ceres/solver.cc
index f8ad2c9..dfde122 100644
--- a/internal/ceres/solver.cc
+++ b/internal/ceres/solver.cc
@@ -56,34 +56,34 @@
 namespace ceres {
 namespace {
 
+using internal::StringAppendF;
+using internal::StringPrintf;
 using std::map;
 using std::string;
 using std::vector;
-using internal::StringAppendF;
-using internal::StringPrintf;
 
-#define OPTION_OP(x, y, OP)                                             \
-  if (!(options.x OP y)) {                                              \
-    std::stringstream ss;                                               \
-    ss << "Invalid configuration. ";                                    \
-    ss << string("Solver::Options::" #x " = ") << options.x << ". ";    \
-    ss << "Violated constraint: ";                                      \
-    ss << string("Solver::Options::" #x " " #OP " "#y);                 \
-    *error = ss.str();                                                  \
-    return false;                                                       \
+#define OPTION_OP(x, y, OP)                                          \
+  if (!(options.x OP y)) {                                           \
+    std::stringstream ss;                                            \
+    ss << "Invalid configuration. ";                                 \
+    ss << string("Solver::Options::" #x " = ") << options.x << ". "; \
+    ss << "Violated constraint: ";                                   \
+    ss << string("Solver::Options::" #x " " #OP " " #y);             \
+    *error = ss.str();                                               \
+    return false;                                                    \
   }
 
-#define OPTION_OP_OPTION(x, y, OP)                                      \
-  if (!(options.x OP options.y)) {                                      \
-    std::stringstream ss;                                               \
-    ss << "Invalid configuration. ";                                    \
-    ss << string("Solver::Options::" #x " = ") << options.x << ". ";    \
-    ss << string("Solver::Options::" #y " = ") << options.y << ". ";    \
-    ss << "Violated constraint: ";                                      \
-    ss << string("Solver::Options::" #x);                               \
-    ss << string(#OP " Solver::Options::" #y ".");                      \
-    *error = ss.str();                                                  \
-    return false;                                                       \
+#define OPTION_OP_OPTION(x, y, OP)                                   \
+  if (!(options.x OP options.y)) {                                   \
+    std::stringstream ss;                                            \
+    ss << "Invalid configuration. ";                                 \
+    ss << string("Solver::Options::" #x " = ") << options.x << ". "; \
+    ss << string("Solver::Options::" #y " = ") << options.y << ". "; \
+    ss << "Violated constraint: ";                                   \
+    ss << string("Solver::Options::" #x);                            \
+    ss << string(#OP " Solver::Options::" #y ".");                   \
+    *error = ss.str();                                               \
+    return false;                                                    \
   }
 
 #define OPTION_GE(x, y) OPTION_OP(x, y, >=);
@@ -128,14 +128,6 @@
     OPTION_GE(inner_iteration_tolerance, 0.0);
   }
 
-  if (options.use_inner_iterations &&
-      options.evaluation_callback != NULL) {
-    *error =  "Inner iterations (use_inner_iterations = true) can't be "
-        "combined with an evaluation callback "
-        "(options.evaluation_callback != NULL).";
-    return false;
-  }
-
   if (options.use_nonmonotonic_steps) {
     OPTION_GT(max_consecutive_nonmonotonic_steps, 0);
   }
@@ -143,7 +135,8 @@
   if (options.linear_solver_type == ITERATIVE_SCHUR &&
       options.use_explicit_schur_complement &&
       options.preconditioner_type != SCHUR_JACOBI) {
-    *error =  "use_explicit_schur_complement only supports "
+    *error =
+        "use_explicit_schur_complement only supports "
         "SCHUR_JACOBI as the preconditioner.";
     return false;
   }
@@ -161,70 +154,81 @@
     return false;
   }
 
-  if (options.sparse_linear_algebra_library_type == NO_SPARSE) {
-    const char* error_template =
-        "Can't use %s with "
-        "Solver::Options::sparse_linear_algebra_library_type = NO_SPARSE.";
-    const char* name = nullptr;
-
-    if (options.linear_solver_type == SPARSE_NORMAL_CHOLESKY ||
-        options.linear_solver_type == SPARSE_SCHUR) {
-      name = LinearSolverTypeToString(options.linear_solver_type);
-    } else if (options.linear_solver_type == ITERATIVE_SCHUR &&
-               (options.preconditioner_type == CLUSTER_JACOBI ||
-                options.preconditioner_type == CLUSTER_TRIDIAGONAL)) {
-      name = PreconditionerTypeToString(options.preconditioner_type);
-    }
-
-    if (name != nullptr) {
-      *error = StringPrintf(error_template, name);
-      return false;
-    }
-  } else if (!IsSparseLinearAlgebraLibraryTypeAvailable(
-                 options.sparse_linear_algebra_library_type)) {
-    const char* error_template =
-        "Can't use %s with "
-        "Solver::Options::sparse_linear_algebra_library_type = %s, "
-        "because support was not enabled when Ceres Solver was built.";
+  {
+    const char* sparse_linear_algebra_library_name =
+        SparseLinearAlgebraLibraryTypeToString(
+            options.sparse_linear_algebra_library_type);
     const char* name = nullptr;
     if (options.linear_solver_type == SPARSE_NORMAL_CHOLESKY ||
         options.linear_solver_type == SPARSE_SCHUR) {
       name = LinearSolverTypeToString(options.linear_solver_type);
-    } else if (options.linear_solver_type == ITERATIVE_SCHUR &&
-               (options.preconditioner_type == CLUSTER_JACOBI ||
-                options.preconditioner_type == CLUSTER_TRIDIAGONAL)) {
+    } else if ((options.linear_solver_type == ITERATIVE_SCHUR &&
+                (options.preconditioner_type == CLUSTER_JACOBI ||
+                 options.preconditioner_type == CLUSTER_TRIDIAGONAL)) ||
+               (options.linear_solver_type == CGNR &&
+                options.preconditioner_type == SUBSET)) {
       name = PreconditionerTypeToString(options.preconditioner_type);
     }
 
-    if (name != nullptr) {
-      *error = StringPrintf(error_template,
-                            name,
-                            SparseLinearAlgebraLibraryTypeToString(
-                                options.sparse_linear_algebra_library_type));
-      return false;
+    if (name) {
+      if (options.sparse_linear_algebra_library_type == NO_SPARSE) {
+        *error = StringPrintf(
+            "Can't use %s with "
+            "Solver::Options::sparse_linear_algebra_library_type = %s.",
+            name,
+            sparse_linear_algebra_library_name);
+        return false;
+      } else if (!IsSparseLinearAlgebraLibraryTypeAvailable(
+                     options.sparse_linear_algebra_library_type)) {
+        *error = StringPrintf(
+            "Can't use %s with "
+            "Solver::Options::sparse_linear_algebra_library_type = %s, "
+            "because support was not enabled when Ceres Solver was built.",
+            name,
+            sparse_linear_algebra_library_name);
+        return false;
+      }
     }
   }
 
   if (options.trust_region_strategy_type == DOGLEG) {
     if (options.linear_solver_type == ITERATIVE_SCHUR ||
         options.linear_solver_type == CGNR) {
-      *error = "DOGLEG only supports exact factorization based linear "
+      *error =
+          "DOGLEG only supports exact factorization based linear "
           "solvers. If you want to use an iterative solver please "
           "use LEVENBERG_MARQUARDT as the trust_region_strategy_type";
       return false;
     }
   }
 
-  if (options.trust_region_minimizer_iterations_to_dump.size() > 0 &&
+  if (!options.trust_region_minimizer_iterations_to_dump.empty() &&
       options.trust_region_problem_dump_format_type != CONSOLE &&
       options.trust_region_problem_dump_directory.empty()) {
     *error = "Solver::Options::trust_region_problem_dump_directory is empty.";
     return false;
   }
 
-  if (options.dynamic_sparsity &&
-      options.linear_solver_type != SPARSE_NORMAL_CHOLESKY) {
-    *error = "Dynamic sparsity is only supported with SPARSE_NORMAL_CHOLESKY.";
+  if (options.dynamic_sparsity) {
+    if (options.linear_solver_type != SPARSE_NORMAL_CHOLESKY) {
+      *error =
+          "Dynamic sparsity is only supported with SPARSE_NORMAL_CHOLESKY.";
+      return false;
+    }
+    if (options.sparse_linear_algebra_library_type == ACCELERATE_SPARSE) {
+      *error =
+          "ACCELERATE_SPARSE is not currently supported with dynamic sparsity.";
+      return false;
+    }
+  }
+
+  if (options.linear_solver_type == CGNR &&
+      options.preconditioner_type == SUBSET &&
+      options.residual_blocks_for_subset_preconditioner.empty()) {
+    *error =
+        "When using SUBSET preconditioner, "
+        "Solver::Options::residual_blocks_for_subset_preconditioner cannot be "
+        "empty";
     return false;
   }
 
@@ -239,7 +243,8 @@
   OPTION_LT_OPTION(max_line_search_step_contraction,
                    min_line_search_step_contraction);
   OPTION_LE(min_line_search_step_contraction, 1.0);
-  OPTION_GT(max_num_line_search_step_size_iterations, 0);
+  OPTION_GE(max_num_line_search_step_size_iterations,
+            (options.minimizer_type == ceres::TRUST_REGION ? 0 : 1));
   OPTION_GT(line_search_sufficient_function_decrease, 0.0);
   OPTION_LT_OPTION(line_search_sufficient_function_decrease,
                    line_search_sufficient_curvature_decrease);
@@ -250,10 +255,11 @@
        options.line_search_direction_type == ceres::LBFGS) &&
       options.line_search_type != ceres::WOLFE) {
     *error =
-        string("Invalid configuration: Solver::Options::line_search_type = ")
-        + string(LineSearchTypeToString(options.line_search_type))
-        + string(". When using (L)BFGS, "
-                 "Solver::Options::line_search_type must be set to WOLFE.");
+        string("Invalid configuration: Solver::Options::line_search_type = ") +
+        string(LineSearchTypeToString(options.line_search_type)) +
+        string(
+            ". When using (L)BFGS, "
+            "Solver::Options::line_search_type must be set to WOLFE.");
     return false;
   }
 
@@ -261,17 +267,18 @@
   // on max/min step size change during line search prevent bisection scaling
   // from occurring. Warn only, as this is likely a user mistake, but one which
   // does not prevent us from continuing.
-  LOG_IF(WARNING,
-         (options.line_search_interpolation_type == ceres::BISECTION &&
-          (options.max_line_search_step_contraction > 0.5 ||
-           options.min_line_search_step_contraction < 0.5)))
-      << "Line search interpolation type is BISECTION, but specified "
-      << "max_line_search_step_contraction: "
-      << options.max_line_search_step_contraction << ", and "
-      << "min_line_search_step_contraction: "
-      << options.min_line_search_step_contraction
-      << ", prevent bisection (0.5) scaling, continuing with solve regardless.";
-
+  if (options.line_search_interpolation_type == ceres::BISECTION &&
+      (options.max_line_search_step_contraction > 0.5 ||
+       options.min_line_search_step_contraction < 0.5)) {
+    LOG(WARNING)
+        << "Line search interpolation type is BISECTION, but specified "
+        << "max_line_search_step_contraction: "
+        << options.max_line_search_step_contraction << ", and "
+        << "min_line_search_step_contraction: "
+        << options.min_line_search_step_contraction
+        << ", prevent bisection (0.5) scaling, continuing with solve "
+           "regardless.";
+  }
   return true;
 }
 
@@ -285,7 +292,7 @@
 #undef OPTION_LT_OPTION
 
 void StringifyOrdering(const vector<int>& ordering, string* report) {
-  if (ordering.size() == 0) {
+  if (ordering.empty()) {
     internal::StringAppendF(report, "AUTOMATIC");
     return;
   }
@@ -298,20 +305,24 @@
 
 void SummarizeGivenProgram(const internal::Program& program,
                            Solver::Summary* summary) {
+  // clang-format off
   summary->num_parameter_blocks     = program.NumParameterBlocks();
   summary->num_parameters           = program.NumParameters();
   summary->num_effective_parameters = program.NumEffectiveParameters();
   summary->num_residual_blocks      = program.NumResidualBlocks();
   summary->num_residuals            = program.NumResiduals();
+  // clang-format on
 }
 
 void SummarizeReducedProgram(const internal::Program& program,
                              Solver::Summary* summary) {
+  // clang-format off
   summary->num_parameter_blocks_reduced     = program.NumParameterBlocks();
   summary->num_parameters_reduced           = program.NumParameters();
   summary->num_effective_parameters_reduced = program.NumEffectiveParameters();
   summary->num_residual_blocks_reduced      = program.NumResidualBlocks();
   summary->num_residuals_reduced            = program.NumResiduals();
+  // clang-format on
 }
 
 void PreSolveSummarize(const Solver::Options& options,
@@ -323,6 +334,7 @@
   internal::OrderingToGroupSizes(options.inner_iteration_ordering.get(),
                                  &(summary->inner_iteration_ordering_given));
 
+  // clang-format off
   summary->dense_linear_algebra_library_type  = options.dense_linear_algebra_library_type;  //  NOLINT
   summary->dogleg_type                        = options.dogleg_type;
   summary->inner_iteration_time_in_seconds    = 0.0;
@@ -344,6 +356,7 @@
   summary->sparse_linear_algebra_library_type = options.sparse_linear_algebra_library_type; //  NOLINT
   summary->trust_region_strategy_type         = options.trust_region_strategy_type;         //  NOLINT
   summary->visibility_clustering_type         = options.visibility_clustering_type;         //  NOLINT
+  // clang-format on
 }
 
 void PostSolveSummarize(const internal::PreprocessedProblem& pp,
@@ -353,10 +366,12 @@
   internal::OrderingToGroupSizes(pp.options.inner_iteration_ordering.get(),
                                  &(summary->inner_iteration_ordering_used));
 
+  // clang-format off
   summary->inner_iterations_used          = pp.inner_iteration_minimizer.get() != NULL;     // NOLINT
   summary->linear_solver_type_used        = pp.linear_solver_options.type;
   summary->num_threads_used               = pp.options.num_threads;
   summary->preconditioner_type_used       = pp.options.preconditioner_type;
+  // clang-format on
 
   internal::SetSummaryFinalCost(summary);
 
@@ -402,17 +417,19 @@
   }
 }
 
-void Minimize(internal::PreprocessedProblem* pp,
-              Solver::Summary* summary) {
-  using internal::Program;
+void Minimize(internal::PreprocessedProblem* pp, Solver::Summary* summary) {
   using internal::Minimizer;
+  using internal::Program;
 
   Program* program = pp->reduced_program.get();
   if (pp->reduced_program->NumParameterBlocks() == 0) {
-    summary->message = "Function tolerance reached. "
+    summary->message =
+        "Function tolerance reached. "
         "No non-constant parameter blocks found.";
     summary->termination_type = CONVERGENCE;
-    VLOG_IF(1, pp->options.logging_type != SILENT) << summary->message;
+    if (pp->options.logging_type != SILENT) {
+      VLOG(1) << summary->message;
+    }
     summary->initial_cost = summary->fixed_cost;
     summary->final_cost = summary->fixed_cost;
     return;
@@ -421,31 +438,29 @@
   const Vector original_reduced_parameters = pp->reduced_parameters;
   std::unique_ptr<Minimizer> minimizer(
       Minimizer::Create(pp->options.minimizer_type));
-  minimizer->Minimize(pp->minimizer_options,
-                      pp->reduced_parameters.data(),
-                      summary);
+  minimizer->Minimize(
+      pp->minimizer_options, pp->reduced_parameters.data(), summary);
 
   program->StateVectorToParameterBlocks(
-      summary->IsSolutionUsable()
-      ? pp->reduced_parameters.data()
-      : original_reduced_parameters.data());
+      summary->IsSolutionUsable() ? pp->reduced_parameters.data()
+                                  : original_reduced_parameters.data());
   program->CopyParameterBlockStateToUserState();
 }
 
 std::string SchurStructureToString(const int row_block_size,
                                    const int e_block_size,
                                    const int f_block_size) {
-  const std::string row =
-      (row_block_size == Eigen::Dynamic)
-      ? "d" : internal::StringPrintf("%d", row_block_size);
+  const std::string row = (row_block_size == Eigen::Dynamic)
+                              ? "d"
+                              : internal::StringPrintf("%d", row_block_size);
 
-  const std::string e =
-      (e_block_size == Eigen::Dynamic)
-      ? "d" : internal::StringPrintf("%d", e_block_size);
+  const std::string e = (e_block_size == Eigen::Dynamic)
+                            ? "d"
+                            : internal::StringPrintf("%d", e_block_size);
 
-  const std::string f =
-      (f_block_size == Eigen::Dynamic)
-      ? "d" : internal::StringPrintf("%d", f_block_size);
+  const std::string f = (f_block_size == Eigen::Dynamic)
+                            ? "d"
+                            : internal::StringPrintf("%d", f_block_size);
 
   return internal::StringPrintf("%s,%s,%s", row.c_str(), e.c_str(), f.c_str());
 }
@@ -491,7 +506,7 @@
     return;
   }
 
-  ProblemImpl* problem_impl = problem->problem_impl_.get();
+  ProblemImpl* problem_impl = problem->impl_.get();
   Program* program = problem_impl->mutable_program();
   PreSolveSummarize(options, problem_impl, summary);
 
@@ -503,12 +518,11 @@
   Solver::Options modified_options = options;
   if (options.check_gradients) {
     modified_options.callbacks.push_back(&gradient_checking_callback);
-    gradient_checking_problem.reset(
-        CreateGradientCheckingProblemImpl(
-            problem_impl,
-            options.gradient_check_numeric_derivative_relative_step_size,
-            options.gradient_check_relative_precision,
-            &gradient_checking_callback));
+    gradient_checking_problem.reset(CreateGradientCheckingProblemImpl(
+        problem_impl,
+        options.gradient_check_numeric_derivative_relative_step_size,
+        options.gradient_check_relative_precision,
+        &gradient_checking_callback));
     problem_impl = gradient_checking_problem.get();
     program = problem_impl->mutable_program();
   }
@@ -524,7 +538,8 @@
       Preprocessor::Create(modified_options.minimizer_type));
   PreprocessedProblem pp;
 
-  const bool status = preprocessor->Preprocess(modified_options, problem_impl, &pp);
+  const bool status =
+      preprocessor->Preprocess(modified_options, problem_impl, &pp);
 
   // We check the linear_solver_options.type rather than
   // modified_options.linear_solver_type because, depending on the
@@ -538,17 +553,16 @@
     int e_block_size;
     int f_block_size;
     DetectStructure(*static_cast<internal::BlockSparseMatrix*>(
-                        pp.minimizer_options.jacobian.get())
-                    ->block_structure(),
+                         pp.minimizer_options.jacobian.get())
+                         ->block_structure(),
                     pp.linear_solver_options.elimination_groups[0],
                     &row_block_size,
                     &e_block_size,
                     &f_block_size);
     summary->schur_structure_given =
         SchurStructureToString(row_block_size, e_block_size, f_block_size);
-    internal::GetBestSchurTemplateSpecialization(&row_block_size,
-                                                 &e_block_size,
-                                                 &f_block_size);
+    internal::GetBestSchurTemplateSpecialization(
+        &row_block_size, &e_block_size, &f_block_size);
     summary->schur_structure_used =
         SchurStructureToString(row_block_size, e_block_size, f_block_size);
   }
@@ -566,7 +580,7 @@
   }
 
   const double postprocessor_start_time = WallTimeInSeconds();
-  problem_impl = problem->problem_impl_.get();
+  problem_impl = problem->impl_.get();
   program = problem_impl->mutable_program();
   // On exit, ensure that the parameter blocks again point at the user
   // provided values and the parameter blocks are numbered according
@@ -595,15 +609,16 @@
 }
 
 string Solver::Summary::BriefReport() const {
-  return StringPrintf("Ceres Solver Report: "
-                      "Iterations: %d, "
-                      "Initial cost: %e, "
-                      "Final cost: %e, "
-                      "Termination: %s",
-                      num_successful_steps + num_unsuccessful_steps,
-                      initial_cost,
-                      final_cost,
-                      TerminationTypeToString(termination_type));
+  return StringPrintf(
+      "Ceres Solver Report: "
+      "Iterations: %d, "
+      "Initial cost: %e, "
+      "Final cost: %e, "
+      "Termination: %s",
+      num_successful_steps + num_unsuccessful_steps,
+      initial_cost,
+      final_cost,
+      TerminationTypeToString(termination_type));
 }
 
 string Solver::Summary::FullReport() const {
@@ -612,28 +627,39 @@
   string report = string("\nSolver Summary (v " + VersionString() + ")\n\n");
 
   StringAppendF(&report, "%45s    %21s\n", "Original", "Reduced");
-  StringAppendF(&report, "Parameter blocks    % 25d% 25d\n",
-                num_parameter_blocks, num_parameter_blocks_reduced);
-  StringAppendF(&report, "Parameters          % 25d% 25d\n",
-                num_parameters, num_parameters_reduced);
+  StringAppendF(&report,
+                "Parameter blocks    % 25d% 25d\n",
+                num_parameter_blocks,
+                num_parameter_blocks_reduced);
+  StringAppendF(&report,
+                "Parameters          % 25d% 25d\n",
+                num_parameters,
+                num_parameters_reduced);
   if (num_effective_parameters_reduced != num_parameters_reduced) {
-    StringAppendF(&report, "Effective parameters% 25d% 25d\n",
-                  num_effective_parameters, num_effective_parameters_reduced);
+    StringAppendF(&report,
+                  "Effective parameters% 25d% 25d\n",
+                  num_effective_parameters,
+                  num_effective_parameters_reduced);
   }
-  StringAppendF(&report, "Residual blocks     % 25d% 25d\n",
-                num_residual_blocks, num_residual_blocks_reduced);
-  StringAppendF(&report, "Residuals           % 25d% 25d\n",
-                num_residuals, num_residuals_reduced);
+  StringAppendF(&report,
+                "Residual blocks     % 25d% 25d\n",
+                num_residual_blocks,
+                num_residual_blocks_reduced);
+  StringAppendF(&report,
+                "Residuals           % 25d% 25d\n",
+                num_residuals,
+                num_residuals_reduced);
 
   if (minimizer_type == TRUST_REGION) {
     // TRUST_SEARCH HEADER
-    StringAppendF(&report, "\nMinimizer                 %19s\n",
-                  "TRUST_REGION");
+    StringAppendF(
+        &report, "\nMinimizer                 %19s\n", "TRUST_REGION");
 
     if (linear_solver_type_used == DENSE_NORMAL_CHOLESKY ||
         linear_solver_type_used == DENSE_SCHUR ||
         linear_solver_type_used == DENSE_QR) {
-      StringAppendF(&report, "\nDense linear algebra library  %15s\n",
+      StringAppendF(&report,
+                    "\nDense linear algebra library  %15s\n",
                     DenseLinearAlgebraLibraryTypeToString(
                         dense_linear_algebra_library_type));
     }
@@ -643,14 +669,15 @@
         (linear_solver_type_used == ITERATIVE_SCHUR &&
          (preconditioner_type_used == CLUSTER_JACOBI ||
           preconditioner_type_used == CLUSTER_TRIDIAGONAL))) {
-      StringAppendF(&report, "\nSparse linear algebra library %15s\n",
+      StringAppendF(&report,
+                    "\nSparse linear algebra library %15s\n",
                     SparseLinearAlgebraLibraryTypeToString(
                         sparse_linear_algebra_library_type));
     }
 
-    StringAppendF(&report, "Trust region strategy     %19s",
-                  TrustRegionStrategyTypeToString(
-                      trust_region_strategy_type));
+    StringAppendF(&report,
+                  "Trust region strategy     %19s",
+                  TrustRegionStrategyTypeToString(trust_region_strategy_type));
     if (trust_region_strategy_type == DOGLEG) {
       if (dogleg_type == TRADITIONAL_DOGLEG) {
         StringAppendF(&report, " (TRADITIONAL)");
@@ -661,28 +688,32 @@
     StringAppendF(&report, "\n");
     StringAppendF(&report, "\n");
 
-    StringAppendF(&report, "%45s    %21s\n", "Given",  "Used");
-    StringAppendF(&report, "Linear solver       %25s%25s\n",
+    StringAppendF(&report, "%45s    %21s\n", "Given", "Used");
+    StringAppendF(&report,
+                  "Linear solver       %25s%25s\n",
                   LinearSolverTypeToString(linear_solver_type_given),
                   LinearSolverTypeToString(linear_solver_type_used));
 
     if (linear_solver_type_given == CGNR ||
         linear_solver_type_given == ITERATIVE_SCHUR) {
-      StringAppendF(&report, "Preconditioner      %25s%25s\n",
+      StringAppendF(&report,
+                    "Preconditioner      %25s%25s\n",
                     PreconditionerTypeToString(preconditioner_type_given),
                     PreconditionerTypeToString(preconditioner_type_used));
     }
 
     if (preconditioner_type_used == CLUSTER_JACOBI ||
         preconditioner_type_used == CLUSTER_TRIDIAGONAL) {
-      StringAppendF(&report, "Visibility clustering%24s%25s\n",
-                    VisibilityClusteringTypeToString(
-                        visibility_clustering_type),
-                    VisibilityClusteringTypeToString(
-                        visibility_clustering_type));
+      StringAppendF(
+          &report,
+          "Visibility clustering%24s%25s\n",
+          VisibilityClusteringTypeToString(visibility_clustering_type),
+          VisibilityClusteringTypeToString(visibility_clustering_type));
     }
-    StringAppendF(&report, "Threads             % 25d% 25d\n",
-                  num_threads_given, num_threads_used);
+    StringAppendF(&report,
+                  "Threads             % 25d% 25d\n",
+                  num_threads_given,
+                  num_threads_used);
 
     string given;
     StringifyOrdering(linear_solver_ordering_given, &given);
@@ -711,68 +742,71 @@
       StringifyOrdering(inner_iteration_ordering_given, &given);
       string used;
       StringifyOrdering(inner_iteration_ordering_used, &used);
-    StringAppendF(&report,
-                  "Inner iteration ordering %20s %24s\n",
-                  given.c_str(),
-                  used.c_str());
+      StringAppendF(&report,
+                    "Inner iteration ordering %20s %24s\n",
+                    given.c_str(),
+                    used.c_str());
     }
   } else {
     // LINE_SEARCH HEADER
     StringAppendF(&report, "\nMinimizer                 %19s\n", "LINE_SEARCH");
 
-
     string line_search_direction_string;
     if (line_search_direction_type == LBFGS) {
       line_search_direction_string = StringPrintf("LBFGS (%d)", max_lbfgs_rank);
     } else if (line_search_direction_type == NONLINEAR_CONJUGATE_GRADIENT) {
-      line_search_direction_string =
-          NonlinearConjugateGradientTypeToString(
-              nonlinear_conjugate_gradient_type);
+      line_search_direction_string = NonlinearConjugateGradientTypeToString(
+          nonlinear_conjugate_gradient_type);
     } else {
       line_search_direction_string =
           LineSearchDirectionTypeToString(line_search_direction_type);
     }
 
-    StringAppendF(&report, "Line search direction     %19s\n",
+    StringAppendF(&report,
+                  "Line search direction     %19s\n",
                   line_search_direction_string.c_str());
 
-    const string line_search_type_string =
-        StringPrintf("%s %s",
-                     LineSearchInterpolationTypeToString(
-                         line_search_interpolation_type),
-                     LineSearchTypeToString(line_search_type));
-    StringAppendF(&report, "Line search type          %19s\n",
+    const string line_search_type_string = StringPrintf(
+        "%s %s",
+        LineSearchInterpolationTypeToString(line_search_interpolation_type),
+        LineSearchTypeToString(line_search_type));
+    StringAppendF(&report,
+                  "Line search type          %19s\n",
                   line_search_type_string.c_str());
     StringAppendF(&report, "\n");
 
-    StringAppendF(&report, "%45s    %21s\n", "Given",  "Used");
-    StringAppendF(&report, "Threads             % 25d% 25d\n",
-                  num_threads_given, num_threads_used);
+    StringAppendF(&report, "%45s    %21s\n", "Given", "Used");
+    StringAppendF(&report,
+                  "Threads             % 25d% 25d\n",
+                  num_threads_given,
+                  num_threads_used);
   }
 
   StringAppendF(&report, "\nCost:\n");
   StringAppendF(&report, "Initial        % 30e\n", initial_cost);
-  if (termination_type != FAILURE &&
-      termination_type != USER_FAILURE) {
+  if (termination_type != FAILURE && termination_type != USER_FAILURE) {
     StringAppendF(&report, "Final          % 30e\n", final_cost);
-    StringAppendF(&report, "Change         % 30e\n",
-                  initial_cost - final_cost);
+    StringAppendF(&report, "Change         % 30e\n", initial_cost - final_cost);
   }
 
-  StringAppendF(&report, "\nMinimizer iterations         % 16d\n",
+  StringAppendF(&report,
+                "\nMinimizer iterations         % 16d\n",
                 num_successful_steps + num_unsuccessful_steps);
 
   // Successful/Unsuccessful steps only matter in the case of the
   // trust region solver. Line search terminates when it encounters
   // the first unsuccessful step.
   if (minimizer_type == TRUST_REGION) {
-    StringAppendF(&report, "Successful steps               % 14d\n",
+    StringAppendF(&report,
+                  "Successful steps               % 14d\n",
                   num_successful_steps);
-    StringAppendF(&report, "Unsuccessful steps             % 14d\n",
+    StringAppendF(&report,
+                  "Unsuccessful steps             % 14d\n",
                   num_unsuccessful_steps);
   }
   if (inner_iterations_used) {
-    StringAppendF(&report, "Steps with inner iterations    % 14d\n",
+    StringAppendF(&report,
+                  "Steps with inner iterations    % 14d\n",
                   num_inner_iteration_steps);
   }
 
@@ -781,53 +815,66 @@
        (minimizer_type == TRUST_REGION && is_constrained));
 
   if (line_search_used) {
-    StringAppendF(&report, "Line search steps              % 14d\n",
+    StringAppendF(&report,
+                  "Line search steps              % 14d\n",
                   num_line_search_steps);
   }
 
   StringAppendF(&report, "\nTime (in seconds):\n");
-  StringAppendF(&report, "Preprocessor        %25.6f\n",
-                preprocessor_time_in_seconds);
+  StringAppendF(
+      &report, "Preprocessor        %25.6f\n", preprocessor_time_in_seconds);
 
-  StringAppendF(&report, "\n  Residual only evaluation %18.6f (%d)\n",
-                residual_evaluation_time_in_seconds, num_residual_evaluations);
+  StringAppendF(&report,
+                "\n  Residual only evaluation %18.6f (%d)\n",
+                residual_evaluation_time_in_seconds,
+                num_residual_evaluations);
   if (line_search_used) {
-    StringAppendF(&report, "    Line search cost evaluation    %10.6f\n",
+    StringAppendF(&report,
+                  "    Line search cost evaluation    %10.6f\n",
                   line_search_cost_evaluation_time_in_seconds);
   }
-  StringAppendF(&report, "  Jacobian & residual evaluation %12.6f (%d)\n",
-                jacobian_evaluation_time_in_seconds, num_jacobian_evaluations);
+  StringAppendF(&report,
+                "  Jacobian & residual evaluation %12.6f (%d)\n",
+                jacobian_evaluation_time_in_seconds,
+                num_jacobian_evaluations);
   if (line_search_used) {
-    StringAppendF(&report, "    Line search gradient evaluation   %6.6f\n",
+    StringAppendF(&report,
+                  "    Line search gradient evaluation   %6.6f\n",
                   line_search_gradient_evaluation_time_in_seconds);
   }
 
   if (minimizer_type == TRUST_REGION) {
-    StringAppendF(&report, "  Linear solver       %23.6f (%d)\n",
-                  linear_solver_time_in_seconds, num_linear_solves);
+    StringAppendF(&report,
+                  "  Linear solver       %23.6f (%d)\n",
+                  linear_solver_time_in_seconds,
+                  num_linear_solves);
   }
 
   if (inner_iterations_used) {
-    StringAppendF(&report, "  Inner iterations    %23.6f\n",
+    StringAppendF(&report,
+                  "  Inner iterations    %23.6f\n",
                   inner_iteration_time_in_seconds);
   }
 
   if (line_search_used) {
-    StringAppendF(&report, "  Line search polynomial minimization  %.6f\n",
+    StringAppendF(&report,
+                  "  Line search polynomial minimization  %.6f\n",
                   line_search_polynomial_minimization_time_in_seconds);
   }
 
-  StringAppendF(&report, "Minimizer           %25.6f\n\n",
-                minimizer_time_in_seconds);
+  StringAppendF(
+      &report, "Minimizer           %25.6f\n\n", minimizer_time_in_seconds);
 
-  StringAppendF(&report, "Postprocessor        %24.6f\n",
-                postprocessor_time_in_seconds);
+  StringAppendF(
+      &report, "Postprocessor        %24.6f\n", postprocessor_time_in_seconds);
 
-  StringAppendF(&report, "Total               %25.6f\n\n",
-                total_time_in_seconds);
+  StringAppendF(
+      &report, "Total               %25.6f\n\n", total_time_in_seconds);
 
-  StringAppendF(&report, "Termination:        %25s (%s)\n",
-                TerminationTypeToString(termination_type), message.c_str());
+  StringAppendF(&report,
+                "Termination:        %25s (%s)\n",
+                TerminationTypeToString(termination_type),
+                message.c_str());
   return report;
 }
 
diff --git a/internal/ceres/solver_test.cc b/internal/ceres/solver_test.cc
index 6acae0b..c4823be 100644
--- a/internal/ceres/solver_test.cc
+++ b/internal/ceres/solver_test.cc
@@ -1,5 +1,5 @@
 // Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2015 Google Inc. All rights reserved.
+// Copyright 2019 Google Inc. All rights reserved.
 // http://ceres-solver.org/
 //
 // Redistribution and use in source and binary forms, with or without
@@ -30,16 +30,18 @@
 
 #include "ceres/solver.h"
 
+#include <cmath>
 #include <limits>
 #include <memory>
-#include <cmath>
 #include <vector>
-#include "gtest/gtest.h"
-#include "ceres/evaluation_callback.h"
+
 #include "ceres/autodiff_cost_function.h"
-#include "ceres/sized_cost_function.h"
+#include "ceres/evaluation_callback.h"
+#include "ceres/local_parameterization.h"
 #include "ceres/problem.h"
 #include "ceres/problem_impl.h"
+#include "ceres/sized_cost_function.h"
+#include "gtest/gtest.h"
 
 namespace ceres {
 namespace internal {
@@ -61,8 +63,8 @@
 }
 
 struct QuadraticCostFunctor {
-  template <typename T> bool operator()(const T* const x,
-                                        T* residual) const {
+  template <typename T>
+  bool operator()(const T* const x, T* residual) const {
     residual[0] = T(5.0) - *x;
     return true;
   }
@@ -74,35 +76,33 @@
 };
 
 struct RememberingCallback : public IterationCallback {
-  explicit RememberingCallback(double *x) : calls(0), x(x) {}
+  explicit RememberingCallback(double* x) : calls(0), x(x) {}
   virtual ~RememberingCallback() {}
-  virtual CallbackReturnType operator()(const IterationSummary& summary) {
+  CallbackReturnType operator()(const IterationSummary& summary) final {
     x_values.push_back(*x);
     return SOLVER_CONTINUE;
   }
   int calls;
-  double *x;
+  double* x;
   std::vector<double> x_values;
 };
 
 struct NoOpEvaluationCallback : EvaluationCallback {
   virtual ~NoOpEvaluationCallback() {}
-  virtual void PrepareForEvaluation(bool evaluate_jacobians,
-                                    bool new_evaluation_point) {
-    (void) evaluate_jacobians;
-    (void) new_evaluation_point;
+  void PrepareForEvaluation(bool evaluate_jacobians,
+                            bool new_evaluation_point) final {
+    (void)evaluate_jacobians;
+    (void)new_evaluation_point;
   }
 };
 
-TEST(Solver, UpdateStateEveryIterationOption) {
+TEST(Solver, UpdateStateEveryIterationOptionNoEvaluationCallback) {
   double x = 50.0;
   const double original_x = x;
 
-  std::unique_ptr<CostFunction> cost_function(QuadraticCostFunctor::Create());
   Problem::Options problem_options;
-  problem_options.cost_function_ownership = DO_NOT_TAKE_OWNERSHIP;
   Problem problem(problem_options);
-  problem.AddResidualBlock(cost_function.get(), NULL, &x);
+  problem.AddResidualBlock(QuadraticCostFunctor::Create(), nullptr, &x);
 
   Solver::Options options;
   options.linear_solver_type = DENSE_QR;
@@ -114,73 +114,104 @@
 
   int num_iterations;
 
-  // There are four cases that need to be checked:
-  //
-  //   (update_state_every_iteration = true|false) X
-  //   (evaluation_callback = NULL|provided)
-  //
-  // These need to get checked since there is some interaction between them.
-
-  // First: update_state_every_iteration=false, evaluation_callback=NULL.
+  // First: update_state_every_iteration=false, evaluation_callback=nullptr.
   Solve(options, &problem, &summary);
-  num_iterations = summary.num_successful_steps +
-                   summary.num_unsuccessful_steps;
+  num_iterations =
+      summary.num_successful_steps + summary.num_unsuccessful_steps;
   EXPECT_GT(num_iterations, 1);
   for (int i = 0; i < callback.x_values.size(); ++i) {
     EXPECT_EQ(50.0, callback.x_values[i]);
   }
 
-  // Second: update_state_every_iteration=true, evaluation_callback=NULL.
+  // Second: update_state_every_iteration=true, evaluation_callback=nullptr.
   x = 50.0;
   options.update_state_every_iteration = true;
   callback.x_values.clear();
   Solve(options, &problem, &summary);
-  num_iterations = summary.num_successful_steps +
-                   summary.num_unsuccessful_steps;
-  EXPECT_GT(num_iterations, 1);
-  EXPECT_EQ(original_x, callback.x_values[0]);
-  EXPECT_NE(original_x, callback.x_values[1]);
-
-  NoOpEvaluationCallback evaluation_callback;
-
-  // Third: update_state_every_iteration=true, evaluation_callback=!NULL.
-  x = 50.0;
-  options.update_state_every_iteration = true;
-  options.evaluation_callback = &evaluation_callback;
-  callback.x_values.clear();
-  Solve(options, &problem, &summary);
-  num_iterations = summary.num_successful_steps +
-                   summary.num_unsuccessful_steps;
-  EXPECT_GT(num_iterations, 1);
-  EXPECT_EQ(original_x, callback.x_values[0]);
-  EXPECT_NE(original_x, callback.x_values[1]);
-
-  // Fourth: update_state_every_iteration=false, evaluation_callback=!NULL.
-  x = 50.0;
-  options.update_state_every_iteration = false;
-  options.evaluation_callback = &evaluation_callback;
-  callback.x_values.clear();
-  Solve(options, &problem, &summary);
-  num_iterations = summary.num_successful_steps +
-                   summary.num_unsuccessful_steps;
+  num_iterations =
+      summary.num_successful_steps + summary.num_unsuccessful_steps;
   EXPECT_GT(num_iterations, 1);
   EXPECT_EQ(original_x, callback.x_values[0]);
   EXPECT_NE(original_x, callback.x_values[1]);
 }
 
+TEST(Solver, UpdateStateEveryIterationOptionWithEvaluationCallback) {
+  double x = 50.0;
+  const double original_x = x;
+
+  Problem::Options problem_options;
+  NoOpEvaluationCallback evaluation_callback;
+  problem_options.evaluation_callback = &evaluation_callback;
+
+  Problem problem(problem_options);
+  problem.AddResidualBlock(QuadraticCostFunctor::Create(), nullptr, &x);
+
+  Solver::Options options;
+  options.linear_solver_type = DENSE_QR;
+  RememberingCallback callback(&x);
+  options.callbacks.push_back(&callback);
+
+  Solver::Summary summary;
+
+  int num_iterations;
+
+  // First: update_state_every_iteration=true, evaluation_callback=!nullptr.
+  x = 50.0;
+  options.update_state_every_iteration = true;
+  callback.x_values.clear();
+  Solve(options, &problem, &summary);
+  num_iterations =
+      summary.num_successful_steps + summary.num_unsuccessful_steps;
+  EXPECT_GT(num_iterations, 1);
+  EXPECT_EQ(original_x, callback.x_values[0]);
+  EXPECT_NE(original_x, callback.x_values[1]);
+
+  // Second: update_state_every_iteration=false, evaluation_callback=!nullptr.
+  x = 50.0;
+  options.update_state_every_iteration = false;
+  callback.x_values.clear();
+  Solve(options, &problem, &summary);
+  num_iterations =
+      summary.num_successful_steps + summary.num_unsuccessful_steps;
+  EXPECT_GT(num_iterations, 1);
+  EXPECT_EQ(original_x, callback.x_values[0]);
+  EXPECT_NE(original_x, callback.x_values[1]);
+}
+
+TEST(Solver, CantMixEvaluationCallbackWithInnerIterations) {
+  double x = 50.0;
+  double y = 60.0;
+
+  Problem::Options problem_options;
+  NoOpEvaluationCallback evaluation_callback;
+  problem_options.evaluation_callback = &evaluation_callback;
+
+  Problem problem(problem_options);
+  problem.AddResidualBlock(QuadraticCostFunctor::Create(), nullptr, &x);
+  problem.AddResidualBlock(QuadraticCostFunctor::Create(), nullptr, &y);
+
+  Solver::Options options;
+  options.use_inner_iterations = true;
+  Solver::Summary summary;
+  Solve(options, &problem, &summary);
+  EXPECT_EQ(summary.termination_type, FAILURE);
+
+  options.use_inner_iterations = false;
+  Solve(options, &problem, &summary);
+  EXPECT_EQ(summary.termination_type, CONVERGENCE);
+}
+
 // The parameters must be in separate blocks so that they can be individually
 // set constant or not.
 struct Quadratic4DCostFunction {
-  template <typename T> bool operator()(const T* const x,
-                                        const T* const y,
-                                        const T* const z,
-                                        const T* const w,
-                                        T* residual) const {
+  template <typename T>
+  bool operator()(const T* const x,
+                  const T* const y,
+                  const T* const z,
+                  const T* const w,
+                  T* residual) const {
     // A 4-dimension axis-aligned quadratic.
-    residual[0] = T(10.0) - *x +
-                  T(20.0) - *y +
-                  T(30.0) - *z +
-                  T(40.0) - *w;
+    residual[0] = T(10.0) - *x + T(20.0) - *y + T(30.0) - *z + T(40.0) - *w;
     return true;
   }
 
@@ -193,11 +224,11 @@
 // A cost function that simply returns its argument.
 class UnaryIdentityCostFunction : public SizedCostFunction<1, 1> {
  public:
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     residuals[0] = parameters[0][0];
-    if (jacobians != NULL && jacobians[0] != NULL) {
+    if (jacobians != nullptr && jacobians[0] != nullptr) {
       jacobians[0][0] = 1.0;
     }
     return true;
@@ -259,7 +290,7 @@
 TEST(Solver, TrustRegionProblemIsConstant) {
   Problem problem;
   double x = 1;
-  problem.AddResidualBlock(new UnaryIdentityCostFunction, NULL, &x);
+  problem.AddResidualBlock(new UnaryIdentityCostFunction, nullptr, &x);
   problem.SetParameterBlockConstant(&x);
   Solver::Options options;
   options.minimizer_type = TRUST_REGION;
@@ -273,7 +304,7 @@
 TEST(Solver, LineSearchProblemIsConstant) {
   Problem problem;
   double x = 1;
-  problem.AddResidualBlock(new UnaryIdentityCostFunction, NULL, &x);
+  problem.AddResidualBlock(new UnaryIdentityCostFunction, nullptr, &x);
   problem.SetParameterBlockConstant(&x);
   Solver::Options options;
   options.minimizer_type = LINE_SEARCH;
@@ -336,6 +367,15 @@
   string message;
   EXPECT_FALSE(options.IsValid(&message));
 }
+#else
+TEST(Solver, DynamicSparseNormalCholeskyUnsupportedWithAccelerateSparse) {
+  Solver::Options options;
+  options.sparse_linear_algebra_library_type = ACCELERATE_SPARSE;
+  options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
+  options.dynamic_sparsity = true;
+  string message;
+  EXPECT_FALSE(options.IsValid(&message));
+}
 #endif
 
 #if !defined(CERES_USE_EIGEN_SPARSE)
@@ -382,7 +422,8 @@
   EXPECT_FALSE(options.IsValid(&message));
 }
 
-TEST(Solver, IterativeSchurWithClusterTridiagonalPerconditionerNoSparseLibrary) {
+TEST(Solver,
+     IterativeSchurWithClusterTridiagonalPerconditionerNoSparseLibrary) {
   Solver::Options options;
   options.sparse_linear_algebra_library_type = NO_SPARSE;
   options.linear_solver_type = ITERATIVE_SCHUR;
@@ -417,9 +458,8 @@
   EXPECT_TRUE(options.IsValid(&message));
 
   options.linear_solver_type = SPARSE_SCHUR;
-#if defined(CERES_NO_SUITESPARSE) &&            \
-    defined(CERES_NO_CXSPARSE) &&               \
-   !defined(CERES_USE_EIGEN_SPARSE)
+#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE) && \
+    !defined(CERES_USE_EIGEN_SPARSE)
   EXPECT_FALSE(options.IsValid(&message));
 #else
   EXPECT_TRUE(options.IsValid(&message));
@@ -429,30 +469,6 @@
   EXPECT_TRUE(options.IsValid(&message));
 }
 
-TEST(Solver, CantMixEvaluationCallbackWithInnerIterations) {
-  Solver::Options options;
-  NoOpEvaluationCallback evaluation_callback;
-  string message;
-
-  // Can't combine them.
-  options.use_inner_iterations = true;
-  options.evaluation_callback = &evaluation_callback;
-  EXPECT_FALSE(options.IsValid(&message));
-
-  // Either or none is OK.
-  options.use_inner_iterations = false;
-  options.evaluation_callback = &evaluation_callback;
-  EXPECT_TRUE(options.IsValid(&message));
-
-  options.use_inner_iterations = true;
-  options.evaluation_callback = NULL;
-  EXPECT_TRUE(options.IsValid(&message));
-
-  options.use_inner_iterations = false;
-  options.evaluation_callback = NULL;
-  EXPECT_TRUE(options.IsValid(&message));
-}
-
 template <int kNumResiduals, int... Ns>
 class DummyCostFunction : public SizedCostFunction<kNumResiduals, Ns...> {
  public:
@@ -470,7 +486,7 @@
 TEST(Solver, FixedCostForConstantProblem) {
   double x = 1.0;
   Problem problem;
-  problem.AddResidualBlock(new DummyCostFunction<2, 1>(), NULL, &x);
+  problem.AddResidualBlock(new DummyCostFunction<2, 1>(), nullptr, &x);
   problem.SetParameterBlockConstant(&x);
   const double expected_cost = 41.0 / 2.0;  // 1/2 * ((4 + 0)^2 + (4 + 1)^2)
   Solver::Options options;
@@ -483,5 +499,38 @@
   EXPECT_EQ(summary.iterations.size(), 0);
 }
 
+struct LinearCostFunction {
+  template <typename T>
+  bool operator()(const T* x, const T* y, T* residual) const {
+    residual[0] = T(10.0) - *x;
+    residual[1] = T(5.0) - *y;
+    return true;
+  }
+  static CostFunction* Create() {
+    return new AutoDiffCostFunction<LinearCostFunction, 2, 1, 1>(
+        new LinearCostFunction);
+  }
+};
+
+TEST(Solver, ZeroSizedLocalParameterizationHoldsParameterBlockConstant) {
+  double x = 0.0;
+  double y = 1.0;
+  Problem problem;
+  problem.AddResidualBlock(LinearCostFunction::Create(), nullptr, &x, &y);
+  problem.SetParameterization(&y, new SubsetParameterization(1, {0}));
+  EXPECT_TRUE(problem.IsParameterBlockConstant(&y));
+
+  Solver::Options options;
+  options.function_tolerance = 0.0;
+  options.gradient_tolerance = 0.0;
+  options.parameter_tolerance = 0.0;
+  Solver::Summary summary;
+  Solve(options, &problem, &summary);
+
+  EXPECT_EQ(summary.termination_type, CONVERGENCE);
+  EXPECT_NEAR(x, 10.0, 1e-7);
+  EXPECT_EQ(y, 1.0);
+}
+
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/solver_utils.cc b/internal/ceres/solver_utils.cc
index 177a928..eb5aafa 100644
--- a/internal/ceres/solver_utils.cc
+++ b/internal/ceres/solver_utils.cc
@@ -28,22 +28,24 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/solver_utils.h"
+
 #include <string>
 
-#include "ceres/internal/config.h"
-
 #include "Eigen/Core"
+#include "ceres/internal/config.h"
 #include "ceres/internal/port.h"
-#include "ceres/solver_utils.h"
 #include "ceres/version.h"
 
 namespace ceres {
 namespace internal {
 
-#define CERES_EIGEN_VERSION                                          \
-  CERES_TO_STRING(EIGEN_WORLD_VERSION) "."                           \
-  CERES_TO_STRING(EIGEN_MAJOR_VERSION) "."                           \
+// clang-format off
+#define CERES_EIGEN_VERSION                 \
+  CERES_TO_STRING(EIGEN_WORLD_VERSION) "."  \
+  CERES_TO_STRING(EIGEN_MAJOR_VERSION) "."  \
   CERES_TO_STRING(EIGEN_MINOR_VERSION)
+// clang-format on
 
 std::string VersionString() {
   std::string value = std::string(CERES_VERSION_STRING);
diff --git a/internal/ceres/sparse_cholesky.cc b/internal/ceres/sparse_cholesky.cc
index 3275cc0..91cdf67 100644
--- a/internal/ceres/sparse_cholesky.cc
+++ b/internal/ceres/sparse_cholesky.cc
@@ -89,7 +89,8 @@
       if (options.use_mixed_precision_solves) {
         sparse_cholesky = AppleAccelerateCholesky<float>::Create(ordering_type);
       } else {
-        sparse_cholesky = AppleAccelerateCholesky<double>::Create(ordering_type);
+        sparse_cholesky =
+            AppleAccelerateCholesky<double>::Create(ordering_type);
       }
       break;
 #else
@@ -126,14 +127,6 @@
   return termination_type;
 }
 
-CompressedRowSparseMatrix::StorageType StorageTypeForSparseLinearAlgebraLibrary(
-    SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type) {
-  if (sparse_linear_algebra_library_type == SUITE_SPARSE) {
-    return CompressedRowSparseMatrix::UPPER_TRIANGULAR;
-  }
-  return CompressedRowSparseMatrix::LOWER_TRIANGULAR;
-}
-
 RefinedSparseCholesky::RefinedSparseCholesky(
     std::unique_ptr<SparseCholesky> sparse_cholesky,
     std::unique_ptr<IterativeRefiner> iterative_refiner)
diff --git a/internal/ceres/sparse_cholesky.h b/internal/ceres/sparse_cholesky.h
index bbe4237..a6af6b2 100644
--- a/internal/ceres/sparse_cholesky.h
+++ b/internal/ceres/sparse_cholesky.h
@@ -32,9 +32,12 @@
 #define CERES_INTERNAL_SPARSE_CHOLESKY_H_
 
 // This include must come before any #ifndef check on Ceres compile options.
+// clang-format off
 #include "ceres/internal/port.h"
+// clang-format on
 
 #include <memory>
+
 #include "ceres/linear_solver.h"
 #include "glog/logging.h"
 
@@ -64,7 +67,7 @@
 //  CHECK_EQ(sparse_cholesky->Solve(rhs.data(), solution.data(), &message),
 //           LINEAR_SOLVER_SUCCESS);
 
-class SparseCholesky {
+class CERES_EXPORT_INTERNAL SparseCholesky {
  public:
   static std::unique_ptr<SparseCholesky> Create(
       const LinearSolver::Options& options);
@@ -88,8 +91,8 @@
   // Subsequent calls to Factorize will use that symbolic
   // factorization assuming that the sparsity of the matrix has
   // remained constant.
-  virtual LinearSolverTerminationType Factorize(
-      CompressedRowSparseMatrix* lhs, std::string* message) = 0;
+  virtual LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
+                                                std::string* message) = 0;
 
   // Computes the solution to the equation
   //
@@ -106,22 +109,21 @@
       const double* rhs,
       double* solution,
       std::string* message);
-
 };
 
 class IterativeRefiner;
 
 // Computes an initial solution using the given instance of
 // SparseCholesky, and then refines it using the IterativeRefiner.
-class RefinedSparseCholesky : public SparseCholesky {
+class CERES_EXPORT_INTERNAL RefinedSparseCholesky : public SparseCholesky {
  public:
   RefinedSparseCholesky(std::unique_ptr<SparseCholesky> sparse_cholesky,
                         std::unique_ptr<IterativeRefiner> iterative_refiner);
   virtual ~RefinedSparseCholesky();
 
   virtual CompressedRowSparseMatrix::StorageType StorageType() const;
-  virtual LinearSolverTerminationType Factorize(
-      CompressedRowSparseMatrix* lhs, std::string* message);
+  virtual LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
+                                                std::string* message);
   virtual LinearSolverTerminationType Solve(const double* rhs,
                                             double* solution,
                                             std::string* message);
diff --git a/internal/ceres/sparse_cholesky_test.cc b/internal/ceres/sparse_cholesky_test.cc
index 4c1f6d8..2ef24e3 100644
--- a/internal/ceres/sparse_cholesky_test.cc
+++ b/internal/ceres/sparse_cholesky_test.cc
@@ -49,6 +49,8 @@
 namespace ceres {
 namespace internal {
 
+namespace {
+
 BlockSparseMatrix* CreateRandomFullRankMatrix(const int num_col_blocks,
                                               const int min_col_block_size,
                                               const int max_col_block_size,
@@ -75,9 +77,9 @@
   return random_matrix.release();
 }
 
-bool ComputeExpectedSolution(const CompressedRowSparseMatrix& lhs,
-                             const Vector& rhs,
-                             Vector* solution) {
+static bool ComputeExpectedSolution(const CompressedRowSparseMatrix& lhs,
+                                    const Vector& rhs,
+                                    Vector* solution) {
   Matrix eigen_lhs;
   lhs.ToDenseMatrix(&eigen_lhs);
   if (lhs.storage_type() == CompressedRowSparseMatrix::UPPER_TRIANGULAR) {
@@ -112,9 +114,9 @@
   LinearSolver::Options sparse_cholesky_options;
   sparse_cholesky_options.sparse_linear_algebra_library_type =
       sparse_linear_algebra_library_type;
-  sparse_cholesky_options.use_postordering  = (ordering_type == AMD);
-  std::unique_ptr<SparseCholesky> sparse_cholesky = SparseCholesky::Create(
-      sparse_cholesky_options);
+  sparse_cholesky_options.use_postordering = (ordering_type == AMD);
+  std::unique_ptr<SparseCholesky> sparse_cholesky =
+      SparseCholesky::Create(sparse_cholesky_options);
   const CompressedRowSparseMatrix::StorageType storage_type =
       sparse_cholesky->StorageType();
 
@@ -136,9 +138,9 @@
 
   EXPECT_TRUE(ComputeExpectedSolution(*lhs, rhs, &expected));
   std::string message;
-  EXPECT_EQ(sparse_cholesky->FactorAndSolve(
-                lhs, rhs.data(), actual.data(), &message),
-            LINEAR_SOLVER_SUCCESS);
+  EXPECT_EQ(
+      sparse_cholesky->FactorAndSolve(lhs, rhs.data(), actual.data(), &message),
+      LINEAR_SOLVER_SUCCESS);
   Matrix eigen_lhs;
   lhs->ToDenseMatrix(&eigen_lhs);
   EXPECT_NEAR((actual - expected).norm() / actual.norm(),
@@ -160,6 +162,8 @@
   return ss.str();
 }
 
+}  // namespace
+
 class SparseCholeskyTest : public ::testing::TestWithParam<Param> {};
 
 TEST_P(SparseCholeskyTest, FactorAndSolve) {
@@ -186,54 +190,58 @@
   }
 }
 
+namespace {
+
 #ifndef CERES_NO_SUITESPARSE
-INSTANTIATE_TEST_CASE_P(SuiteSparseCholesky,
-                        SparseCholeskyTest,
-                        ::testing::Combine(::testing::Values(SUITE_SPARSE),
-                                           ::testing::Values(AMD, NATURAL),
-                                           ::testing::Values(true, false)),
-                        ParamInfoToString);
+INSTANTIATE_TEST_SUITE_P(SuiteSparseCholesky,
+                         SparseCholeskyTest,
+                         ::testing::Combine(::testing::Values(SUITE_SPARSE),
+                                            ::testing::Values(AMD, NATURAL),
+                                            ::testing::Values(true, false)),
+                         ParamInfoToString);
 #endif
 
 #ifndef CERES_NO_CXSPARSE
-INSTANTIATE_TEST_CASE_P(CXSparseCholesky,
-                        SparseCholeskyTest,
-                        ::testing::Combine(::testing::Values(CX_SPARSE),
-                                           ::testing::Values(AMD, NATURAL),
-                                           ::testing::Values(true, false)),
-                        ParamInfoToString);
+INSTANTIATE_TEST_SUITE_P(CXSparseCholesky,
+                         SparseCholeskyTest,
+                         ::testing::Combine(::testing::Values(CX_SPARSE),
+                                            ::testing::Values(AMD, NATURAL),
+                                            ::testing::Values(true, false)),
+                         ParamInfoToString);
 #endif
 
 #ifndef CERES_NO_ACCELERATE_SPARSE
-INSTANTIATE_TEST_CASE_P(AccelerateSparseCholesky,
-                        SparseCholeskyTest,
-                        ::testing::Combine(::testing::Values(ACCELERATE_SPARSE),
-                                           ::testing::Values(AMD, NATURAL),
-                                           ::testing::Values(true, false)),
-                        ParamInfoToString);
+INSTANTIATE_TEST_SUITE_P(
+    AccelerateSparseCholesky,
+    SparseCholeskyTest,
+    ::testing::Combine(::testing::Values(ACCELERATE_SPARSE),
+                       ::testing::Values(AMD, NATURAL),
+                       ::testing::Values(true, false)),
+    ParamInfoToString);
 
-INSTANTIATE_TEST_CASE_P(AccelerateSparseCholeskySingle,
-                        SparseCholeskyTest,
-                        ::testing::Combine(::testing::Values(ACCELERATE_SPARSE),
-                                           ::testing::Values(AMD, NATURAL),
-                                           ::testing::Values(true, false)),
-                        ParamInfoToString);
+INSTANTIATE_TEST_SUITE_P(
+    AccelerateSparseCholeskySingle,
+    SparseCholeskyTest,
+    ::testing::Combine(::testing::Values(ACCELERATE_SPARSE),
+                       ::testing::Values(AMD, NATURAL),
+                       ::testing::Values(true, false)),
+    ParamInfoToString);
 #endif
 
 #ifdef CERES_USE_EIGEN_SPARSE
-INSTANTIATE_TEST_CASE_P(EigenSparseCholesky,
-                        SparseCholeskyTest,
-                        ::testing::Combine(::testing::Values(EIGEN_SPARSE),
-                                           ::testing::Values(AMD, NATURAL),
-                                           ::testing::Values(true, false)),
-                        ParamInfoToString);
+INSTANTIATE_TEST_SUITE_P(EigenSparseCholesky,
+                         SparseCholeskyTest,
+                         ::testing::Combine(::testing::Values(EIGEN_SPARSE),
+                                            ::testing::Values(AMD, NATURAL),
+                                            ::testing::Values(true, false)),
+                         ParamInfoToString);
 
-INSTANTIATE_TEST_CASE_P(EigenSparseCholeskySingle,
-                        SparseCholeskyTest,
-                        ::testing::Combine(::testing::Values(EIGEN_SPARSE),
-                                           ::testing::Values(AMD, NATURAL),
-                                           ::testing::Values(true, false)),
-                        ParamInfoToString);
+INSTANTIATE_TEST_SUITE_P(EigenSparseCholeskySingle,
+                         SparseCholeskyTest,
+                         ::testing::Combine(::testing::Values(EIGEN_SPARSE),
+                                            ::testing::Values(AMD, NATURAL),
+                                            ::testing::Values(true, false)),
+                         ParamInfoToString);
 #endif
 
 class MockSparseCholesky : public SparseCholesky {
@@ -252,13 +260,12 @@
  public:
   MockIterativeRefiner() : IterativeRefiner(1) {}
   MOCK_METHOD4(Refine,
-               void (const SparseMatrix& lhs,
-                     const double* rhs,
-                     SparseCholesky* sparse_cholesky,
-                     double* solution));
+               void(const SparseMatrix& lhs,
+                    const double* rhs,
+                    SparseCholesky* sparse_cholesky,
+                    double* solution));
 };
 
-
 using testing::_;
 using testing::Return;
 
@@ -268,8 +275,7 @@
   EXPECT_CALL(*mock_sparse_cholesky, StorageType())
       .Times(1)
       .WillRepeatedly(Return(CompressedRowSparseMatrix::UPPER_TRIANGULAR));
-  EXPECT_CALL(*mock_iterative_refiner, Refine(_, _, _, _))
-      .Times(0);
+  EXPECT_CALL(*mock_iterative_refiner, Refine(_, _, _, _)).Times(0);
   std::unique_ptr<SparseCholesky> sparse_cholesky(mock_sparse_cholesky);
   std::unique_ptr<IterativeRefiner> iterative_refiner(mock_iterative_refiner);
   RefinedSparseCholesky refined_sparse_cholesky(std::move(sparse_cholesky),
@@ -284,8 +290,7 @@
   EXPECT_CALL(*mock_sparse_cholesky, Factorize(_, _))
       .Times(1)
       .WillRepeatedly(Return(LINEAR_SOLVER_SUCCESS));
-  EXPECT_CALL(*mock_iterative_refiner, Refine(_, _, _, _))
-      .Times(0);
+  EXPECT_CALL(*mock_iterative_refiner, Refine(_, _, _, _)).Times(0);
   std::unique_ptr<SparseCholesky> sparse_cholesky(mock_sparse_cholesky);
   std::unique_ptr<IterativeRefiner> iterative_refiner(mock_iterative_refiner);
   RefinedSparseCholesky refined_sparse_cholesky(std::move(sparse_cholesky),
@@ -302,10 +307,8 @@
   EXPECT_CALL(*mock_sparse_cholesky, Factorize(_, _))
       .Times(1)
       .WillRepeatedly(Return(LINEAR_SOLVER_FAILURE));
-  EXPECT_CALL(*mock_sparse_cholesky, Solve(_, _, _))
-      .Times(0);
-  EXPECT_CALL(*mock_iterative_refiner, Refine(_, _, _, _))
-      .Times(0);
+  EXPECT_CALL(*mock_sparse_cholesky, Solve(_, _, _)).Times(0);
+  EXPECT_CALL(*mock_iterative_refiner, Refine(_, _, _, _)).Times(0);
   std::unique_ptr<SparseCholesky> sparse_cholesky(mock_sparse_cholesky);
   std::unique_ptr<IterativeRefiner> iterative_refiner(mock_iterative_refiner);
   RefinedSparseCholesky refined_sparse_cholesky(std::move(sparse_cholesky),
@@ -314,33 +317,38 @@
   std::string message;
   double rhs;
   double solution;
-  EXPECT_EQ(refined_sparse_cholesky.FactorAndSolve(&m, &rhs, &solution, &message),
-            LINEAR_SOLVER_FAILURE);
+  EXPECT_EQ(
+      refined_sparse_cholesky.FactorAndSolve(&m, &rhs, &solution, &message),
+      LINEAR_SOLVER_FAILURE);
 };
 
 TEST(RefinedSparseCholesky, FactorAndSolveWithSuccess) {
   MockSparseCholesky* mock_sparse_cholesky = new MockSparseCholesky;
-  std::unique_ptr<MockIterativeRefiner> mock_iterative_refiner(new MockIterativeRefiner);
+  std::unique_ptr<MockIterativeRefiner> mock_iterative_refiner(
+      new MockIterativeRefiner);
   EXPECT_CALL(*mock_sparse_cholesky, Factorize(_, _))
       .Times(1)
       .WillRepeatedly(Return(LINEAR_SOLVER_SUCCESS));
   EXPECT_CALL(*mock_sparse_cholesky, Solve(_, _, _))
       .Times(1)
       .WillRepeatedly(Return(LINEAR_SOLVER_SUCCESS));
-  EXPECT_CALL(*mock_iterative_refiner, Refine(_, _, _, _))
-      .Times(1);
+  EXPECT_CALL(*mock_iterative_refiner, Refine(_, _, _, _)).Times(1);
 
   std::unique_ptr<SparseCholesky> sparse_cholesky(mock_sparse_cholesky);
-  std::unique_ptr<IterativeRefiner> iterative_refiner(std::move(mock_iterative_refiner));
+  std::unique_ptr<IterativeRefiner> iterative_refiner(
+      std::move(mock_iterative_refiner));
   RefinedSparseCholesky refined_sparse_cholesky(std::move(sparse_cholesky),
                                                 std::move(iterative_refiner));
   CompressedRowSparseMatrix m(1, 1, 1);
   std::string message;
   double rhs;
   double solution;
-  EXPECT_EQ(refined_sparse_cholesky.FactorAndSolve(&m, &rhs, &solution, &message),
-            LINEAR_SOLVER_SUCCESS);
+  EXPECT_EQ(
+      refined_sparse_cholesky.FactorAndSolve(&m, &rhs, &solution, &message),
+      LINEAR_SOLVER_SUCCESS);
 };
 
+}  // namespace
+
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/sparse_matrix.cc b/internal/ceres/sparse_matrix.cc
index f95ff32..32388f5 100644
--- a/internal/ceres/sparse_matrix.cc
+++ b/internal/ceres/sparse_matrix.cc
@@ -33,8 +33,7 @@
 namespace ceres {
 namespace internal {
 
-SparseMatrix::~SparseMatrix() {
-}
+SparseMatrix::~SparseMatrix() {}
 
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/sparse_matrix.h b/internal/ceres/sparse_matrix.h
index 074d847..b57f108 100644
--- a/internal/ceres/sparse_matrix.h
+++ b/internal/ceres/sparse_matrix.h
@@ -34,8 +34,10 @@
 #define CERES_INTERNAL_SPARSE_MATRIX_H_
 
 #include <cstdio>
-#include "ceres/linear_operator.h"
+
 #include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
+#include "ceres/linear_operator.h"
 #include "ceres/types.h"
 
 namespace ceres {
@@ -62,7 +64,7 @@
 // matrix type dependent and we are at this stage unable to come up
 // with an efficient high level interface that spans multiple sparse
 // matrix types.
-class SparseMatrix : public LinearOperator {
+class CERES_EXPORT_INTERNAL SparseMatrix : public LinearOperator {
  public:
   virtual ~SparseMatrix();
 
diff --git a/internal/ceres/sparse_normal_cholesky_solver.h b/internal/ceres/sparse_normal_cholesky_solver.h
index 95d5436..ef32743 100644
--- a/internal/ceres/sparse_normal_cholesky_solver.h
+++ b/internal/ceres/sparse_normal_cholesky_solver.h
@@ -35,9 +35,12 @@
 #define CERES_INTERNAL_SPARSE_NORMAL_CHOLESKY_SOLVER_H_
 
 // This include must come before any #ifndef check on Ceres compile options.
+// clang-format off
 #include "ceres/internal/port.h"
+// clang-format on
 
 #include <vector>
+
 #include "ceres/linear_solver.h"
 
 namespace ceres {
@@ -58,11 +61,10 @@
   virtual ~SparseNormalCholeskySolver();
 
  private:
-  virtual LinearSolver::Summary SolveImpl(
-      BlockSparseMatrix* A,
-      const double* b,
-      const LinearSolver::PerSolveOptions& options,
-      double* x);
+  LinearSolver::Summary SolveImpl(BlockSparseMatrix* A,
+                                  const double* b,
+                                  const LinearSolver::PerSolveOptions& options,
+                                  double* x) final;
 
   const LinearSolver::Options options_;
   Vector rhs_;
diff --git a/internal/ceres/sparse_normal_cholesky_solver_test.cc b/internal/ceres/sparse_normal_cholesky_solver_test.cc
index c4b4a0b..8acb98e 100644
--- a/internal/ceres/sparse_normal_cholesky_solver_test.cc
+++ b/internal/ceres/sparse_normal_cholesky_solver_test.cc
@@ -29,6 +29,8 @@
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
 #include <memory>
+
+#include "Eigen/Cholesky"
 #include "ceres/block_sparse_matrix.h"
 #include "ceres/casts.h"
 #include "ceres/context_impl.h"
@@ -39,8 +41,6 @@
 #include "glog/logging.h"
 #include "gtest/gtest.h"
 
-#include "Eigen/Cholesky"
-
 namespace ceres {
 namespace internal {
 
@@ -53,7 +53,7 @@
 // classes.
 class SparseNormalCholeskySolverTest : public ::testing::Test {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     std::unique_ptr<LinearLeastSquaresProblem> problem(
         CreateLinearLeastSquaresProblemFromId(2));
 
diff --git a/internal/ceres/split.cc b/internal/ceres/split.cc
index 3a09e86..804f441 100644
--- a/internal/ceres/split.cc
+++ b/internal/ceres/split.cc
@@ -75,10 +75,9 @@
 }
 
 template <typename StringType, typename ITR>
-static inline
-void SplitStringToIteratorUsing(const StringType& full,
-                                const char* delim,
-                                ITR& result) {
+static inline void SplitStringToIteratorUsing(const StringType& full,
+                                              const char* delim,
+                                              ITR& result) {
   // Optimize the common case where delim is a single character.
   if (delim[0] != '\0' && delim[1] == '\0') {
     char c = delim[0];
diff --git a/internal/ceres/split.h b/internal/ceres/split.h
index 94b773d..f513023 100644
--- a/internal/ceres/split.h
+++ b/internal/ceres/split.h
@@ -33,6 +33,7 @@
 
 #include <string>
 #include <vector>
+
 #include "ceres/internal/port.h"
 
 namespace ceres {
@@ -41,7 +42,8 @@
 // Split a string using one or more character delimiters, presented as a
 // nul-terminated c string. Append the components to 'result'. If there are
 // consecutive delimiters, this function skips over all of them.
-void SplitStringUsing(const std::string& full, const char* delim,
+void SplitStringUsing(const std::string& full,
+                      const char* delim,
                       std::vector<std::string>* res);
 
 }  // namespace internal
diff --git a/internal/ceres/stl_util.h b/internal/ceres/stl_util.h
index 0595a4c..d3411b7 100644
--- a/internal/ceres/stl_util.h
+++ b/internal/ceres/stl_util.h
@@ -46,8 +46,7 @@
 // advanced, which could result in the hash function trying to deference a
 // stale pointer.
 template <class ForwardIterator>
-void STLDeleteContainerPointers(ForwardIterator begin,
-                                ForwardIterator end) {
+void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) {
   while (begin != end) {
     ForwardIterator temp = begin;
     ++begin;
@@ -80,7 +79,7 @@
 // ElementDeleter (defined below), which ensures that your container's elements
 // are deleted when the ElementDeleter goes out of scope.
 template <class T>
-void STLDeleteElements(T *container) {
+void STLDeleteElements(T* container) {
   if (!container) return;
   STLDeleteContainerPointers(container->begin(), container->end());
   container->clear();
diff --git a/internal/ceres/stringprintf.cc b/internal/ceres/stringprintf.cc
index b3b7474..b0e2acc 100644
--- a/internal/ceres/stringprintf.cc
+++ b/internal/ceres/stringprintf.cc
@@ -43,28 +43,6 @@
 
 using std::string;
 
-// va_copy() was defined in the C99 standard.  However, it did not appear in the
-// C++ standard until C++11.  This means that if Ceres is being compiled with a
-// strict pre-C++11 standard (e.g. -std=c++03), va_copy() will NOT be defined,
-// as we are using the C++ compiler (it would however be defined if we were
-// using the C compiler).  Note however that both GCC & Clang will in fact
-// define va_copy() when compiling for C++ if the C++ standard is not explicitly
-// specified (i.e. no -std=c++<XX> arg), even though it should not strictly be
-// defined unless -std=c++11 (or greater) was passed.
-#if !defined(va_copy)
-#if defined (__GNUC__)
-// On GCC/Clang, if va_copy() is not defined (C++ standard < C++11 explicitly
-// specified), use the internal __va_copy() version, which should be present
-// in even very old GCC versions.
-#define va_copy(d, s) __va_copy(d, s)
-#else
-// Some older versions of MSVC do not have va_copy(), in which case define it.
-// Although this is required for older MSVC versions, it should also work for
-// other non-GCC/Clang compilers which also do not defined va_copy().
-#define va_copy(d, s) ((d) = (s))
-#endif  // defined (__GNUC__)
-#endif  // !defined(va_copy)
-
 void StringAppendV(string* dst, const char* format, va_list ap) {
   // First try with a small fixed size buffer
   char space[1024];
@@ -84,7 +62,7 @@
       return;
     }
 
-#if defined (_MSC_VER)
+#if defined(_MSC_VER)
     // Error or MSVC running out of space.  MSVC 8.0 and higher
     // can be asked about space needed with the special idiom below:
     va_copy(backup_ap, ap);
@@ -100,7 +78,7 @@
 
   // Increase the buffer size to the size requested by vsnprintf,
   // plus one for the closing \0.
-  int length = result+1;
+  int length = result + 1;
   char* buf = new char[length];
 
   // Restore the va_list before we use it again
@@ -115,7 +93,6 @@
   delete[] buf;
 }
 
-
 string StringPrintf(const char* format, ...) {
   va_list ap;
   va_start(ap, format);
diff --git a/internal/ceres/stringprintf.h b/internal/ceres/stringprintf.h
index feeb9c2..4d51278 100644
--- a/internal/ceres/stringprintf.h
+++ b/internal/ceres/stringprintf.h
@@ -55,31 +55,36 @@
 // have an implicit 'this' argument, the arguments of such methods
 // should be counted from two, not one."
 #define CERES_PRINTF_ATTRIBUTE(string_index, first_to_check) \
-    __attribute__((__format__ (__printf__, string_index, first_to_check)))
+  __attribute__((__format__(__printf__, string_index, first_to_check)))
 #define CERES_SCANF_ATTRIBUTE(string_index, first_to_check) \
-    __attribute__((__format__ (__scanf__, string_index, first_to_check)))
+  __attribute__((__format__(__scanf__, string_index, first_to_check)))
 #else
 #define CERES_PRINTF_ATTRIBUTE(string_index, first_to_check)
 #endif
 
 // Return a C++ string.
-extern std::string StringPrintf(const char* format, ...)
+CERES_EXPORT_INTERNAL extern std::string StringPrintf(const char* format, ...)
     // Tell the compiler to do printf format string checking.
     CERES_PRINTF_ATTRIBUTE(1, 2);
 
 // Store result into a supplied string and return it.
-extern const std::string& SStringPrintf(std::string* dst, const char* format, ...)
+CERES_EXPORT_INTERNAL extern const std::string& SStringPrintf(
+    std::string* dst, const char* format, ...)
     // Tell the compiler to do printf format string checking.
     CERES_PRINTF_ATTRIBUTE(2, 3);
 
 // Append result to a supplied string.
-extern void StringAppendF(std::string* dst, const char* format, ...)
+CERES_EXPORT_INTERNAL extern void StringAppendF(std::string* dst,
+                                                const char* format,
+                                                ...)
     // Tell the compiler to do printf format string checking.
     CERES_PRINTF_ATTRIBUTE(2, 3);
 
 // Lower-level routine that takes a va_list and appends to a specified string.
 // All other routines are just convenience wrappers around it.
-extern void StringAppendV(std::string* dst, const char* format, va_list ap);
+CERES_EXPORT_INTERNAL extern void StringAppendV(std::string* dst,
+                                                const char* format,
+                                                va_list ap);
 
 #undef CERES_PRINTF_ATTRIBUTE
 
diff --git a/internal/ceres/subset_preconditioner.cc b/internal/ceres/subset_preconditioner.cc
index 865c5f1..779a34a 100644
--- a/internal/ceres/subset_preconditioner.cc
+++ b/internal/ceres/subset_preconditioner.cc
@@ -32,6 +32,7 @@
 
 #include <memory>
 #include <string>
+
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/inner_product_computer.h"
 #include "ceres/linear_solver.h"
@@ -44,12 +45,13 @@
 SubsetPreconditioner::SubsetPreconditioner(
     const Preconditioner::Options& options, const BlockSparseMatrix& A)
     : options_(options), num_cols_(A.num_cols()) {
-  CHECK_GE(options_.subset_preconditioner_start_row_block, 0);
+  CHECK_GE(options_.subset_preconditioner_start_row_block, 0)
+      << "Congratulations, you found a bug in Ceres. Please report it.";
+
   LinearSolver::Options sparse_cholesky_options;
   sparse_cholesky_options.sparse_linear_algebra_library_type =
       options_.sparse_linear_algebra_library_type;
-  sparse_cholesky_options.use_postordering =
-      options_.use_postordering;
+  sparse_cholesky_options.use_postordering = options_.use_postordering;
   sparse_cholesky_ = SparseCholesky::Create(sparse_cholesky_options);
 }
 
diff --git a/internal/ceres/subset_preconditioner.h b/internal/ceres/subset_preconditioner.h
index 77c3d91..9844a66 100644
--- a/internal/ceres/subset_preconditioner.h
+++ b/internal/ceres/subset_preconditioner.h
@@ -32,6 +32,8 @@
 #define CERES_INTERNAL_SUBSET_PRECONDITIONER_H_
 
 #include <memory>
+
+#include "ceres/internal/port.h"
 #include "ceres/preconditioner.h"
 
 namespace ceres {
@@ -58,26 +60,27 @@
 // A = [P]
 //     [Q]
 //
-// where P as subset_preconditioner_start_row_block row blocks,
+// where P has subset_preconditioner_start_row_block row blocks,
 // and the preconditioner is the inverse of the matrix Q'Q.
 //
 // Obviously, the smaller this number, the more accurate and
 // computationally expensive this preconditioner will be.
 //
 // See the tests for example usage.
-class SubsetPreconditioner : public BlockSparseMatrixPreconditioner {
+class CERES_EXPORT_INTERNAL SubsetPreconditioner
+    : public BlockSparseMatrixPreconditioner {
  public:
   SubsetPreconditioner(const Preconditioner::Options& options,
                        const BlockSparseMatrix& A);
   virtual ~SubsetPreconditioner();
 
   // Preconditioner interface
-  virtual void RightMultiply(const double* x, double* y) const;
-  virtual int num_rows() const { return num_cols_; }
-  virtual int num_cols() const { return num_cols_; }
+  void RightMultiply(const double* x, double* y) const final;
+  int num_rows() const final { return num_cols_; }
+  int num_cols() const final { return num_cols_; }
 
  private:
-  virtual bool UpdateImpl(const BlockSparseMatrix& A, const double* D);
+  bool UpdateImpl(const BlockSparseMatrix& A, const double* D) final;
 
   const Preconditioner::Options options_;
   const int num_cols_;
diff --git a/internal/ceres/subset_preconditioner_test.cc b/internal/ceres/subset_preconditioner_test.cc
index 0285680..202110b 100644
--- a/internal/ceres/subset_preconditioner_test.cc
+++ b/internal/ceres/subset_preconditioner_test.cc
@@ -28,8 +28,10 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
-#include <memory>
 #include "ceres/subset_preconditioner.h"
+
+#include <memory>
+
 #include "Eigen/Dense"
 #include "Eigen/SparseCore"
 #include "ceres/block_sparse_matrix.h"
@@ -42,6 +44,8 @@
 namespace ceres {
 namespace internal {
 
+namespace {
+
 // TODO(sameeragarwal): Refactor the following two functions out of
 // here and sparse_cholesky_test.cc into a more suitable place.
 template <int UpLoType>
@@ -81,9 +85,11 @@
   return ss.str();
 }
 
+}  // namespace
+
 class SubsetPreconditionerTest : public ::testing::TestWithParam<Param> {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     BlockSparseMatrix::RandomMatrixOptions options;
     options.num_col_blocks = 4;
     options.min_col_block_size = 1;
@@ -167,35 +173,36 @@
 }
 
 #ifndef CERES_NO_SUITESPARSE
-INSTANTIATE_TEST_CASE_P(SubsetPreconditionerWithSuiteSparse,
-                        SubsetPreconditionerTest,
-                        ::testing::Combine(::testing::Values(SUITE_SPARSE),
-                                           ::testing::Values(true, false)),
-                        ParamInfoToString);
+INSTANTIATE_TEST_SUITE_P(SubsetPreconditionerWithSuiteSparse,
+                         SubsetPreconditionerTest,
+                         ::testing::Combine(::testing::Values(SUITE_SPARSE),
+                                            ::testing::Values(true, false)),
+                         ParamInfoToString);
 #endif
 
 #ifndef CERES_NO_CXSPARSE
-INSTANTIATE_TEST_CASE_P(SubsetPreconditionerWithCXSparse,
-                        SubsetPreconditionerTest,
-                        ::testing::Combine(::testing::Values(CX_SPARSE),
-                                           ::testing::Values(true, false)),
-                        ParamInfoToString);
+INSTANTIATE_TEST_SUITE_P(SubsetPreconditionerWithCXSparse,
+                         SubsetPreconditionerTest,
+                         ::testing::Combine(::testing::Values(CX_SPARSE),
+                                            ::testing::Values(true, false)),
+                         ParamInfoToString);
 #endif
 
 #ifndef CERES_NO_ACCELERATE_SPARSE
-INSTANTIATE_TEST_CASE_P(SubsetPreconditionerWithAccelerateSparse,
-                        SubsetPreconditionerTest,
-                        ::testing::Combine(::testing::Values(ACCELERATE_SPARSE),
-                                           ::testing::Values(true, false)),
-                        ParamInfoToString);
+INSTANTIATE_TEST_SUITE_P(
+    SubsetPreconditionerWithAccelerateSparse,
+    SubsetPreconditionerTest,
+    ::testing::Combine(::testing::Values(ACCELERATE_SPARSE),
+                       ::testing::Values(true, false)),
+    ParamInfoToString);
 #endif
 
 #ifdef CERES_USE_EIGEN_SPARSE
-INSTANTIATE_TEST_CASE_P(SubsetPreconditionerWithEigenSparse,
-                        SubsetPreconditionerTest,
-                        ::testing::Combine(::testing::Values(EIGEN_SPARSE),
-                                           ::testing::Values(true, false)),
-                        ParamInfoToString);
+INSTANTIATE_TEST_SUITE_P(SubsetPreconditionerWithEigenSparse,
+                         SubsetPreconditionerTest,
+                         ::testing::Combine(::testing::Values(EIGEN_SPARSE),
+                                            ::testing::Values(true, false)),
+                         ParamInfoToString);
 #endif
 
 }  // namespace internal
diff --git a/internal/ceres/suitesparse.cc b/internal/ceres/suitesparse.cc
index 190d175..0d6f6bd 100644
--- a/internal/ceres/suitesparse.cc
+++ b/internal/ceres/suitesparse.cc
@@ -32,13 +32,12 @@
 #include "ceres/internal/port.h"
 
 #ifndef CERES_NO_SUITESPARSE
-#include "ceres/suitesparse.h"
-
 #include <vector>
 
 #include "ceres/compressed_col_sparse_matrix_utils.h"
 #include "ceres/compressed_row_sparse_matrix.h"
 #include "ceres/linear_solver.h"
+#include "ceres/suitesparse.h"
 #include "ceres/triplet_sparse_matrix.h"
 #include "cholmod.h"
 
@@ -353,7 +352,8 @@
 
 std::unique_ptr<SparseCholesky> SuiteSparseCholesky::Create(
     const OrderingType ordering_type) {
-  return std::unique_ptr<SparseCholesky>(new SuiteSparseCholesky(ordering_type));
+  return std::unique_ptr<SparseCholesky>(
+      new SuiteSparseCholesky(ordering_type));
 }
 
 SuiteSparseCholesky::SuiteSparseCholesky(const OrderingType ordering_type)
diff --git a/internal/ceres/suitesparse.h b/internal/ceres/suitesparse.h
index 7770d9e..5dcc53f 100644
--- a/internal/ceres/suitesparse.h
+++ b/internal/ceres/suitesparse.h
@@ -41,6 +41,7 @@
 #include <cstring>
 #include <string>
 #include <vector>
+
 #include "SuiteSparseQR.hpp"
 #include "ceres/linear_solver.h"
 #include "ceres/sparse_cholesky.h"
@@ -116,20 +117,23 @@
   // for symmetric scaling which scales both the rows and the columns
   // - diag(scale) * A * diag(scale).
   void Scale(cholmod_dense* scale, int mode, cholmod_sparse* A) {
-     cholmod_scale(scale, mode, A, &cc_);
+    cholmod_scale(scale, mode, A, &cc_);
   }
 
   // Create and return a matrix m = A * A'. Caller owns the
   // result. The matrix A is not modified.
   cholmod_sparse* AATranspose(cholmod_sparse* A) {
-    cholmod_sparse*m =  cholmod_aat(A, NULL, A->nrow, 1, &cc_);
+    cholmod_sparse* m = cholmod_aat(A, NULL, A->nrow, 1, &cc_);
     m->stype = 1;  // Pay attention to the upper triangular part.
     return m;
   }
 
   // y = alpha * A * x + beta * y. Only y is modified.
-  void SparseDenseMultiply(cholmod_sparse* A, double alpha, double beta,
-                           cholmod_dense* x, cholmod_dense* y) {
+  void SparseDenseMultiply(cholmod_sparse* A,
+                           double alpha,
+                           double beta,
+                           cholmod_dense* x,
+                           cholmod_dense* y) {
     double alpha_[2] = {alpha, 0};
     double beta_[2] = {beta, 0};
     cholmod_sdmult(A, 0, alpha_, beta_, x, y, &cc_);
@@ -195,7 +199,9 @@
   // NULL is returned. Caller owns the result.
   //
   // message contains an explanation of the failures if any.
-  cholmod_dense* Solve(cholmod_factor* L, cholmod_dense* b, std::string* message);
+  cholmod_dense* Solve(cholmod_factor* L,
+                       cholmod_dense* b,
+                       std::string* message);
 
   // By virtue of the modeling layer in Ceres being block oriented,
   // all the matrices used by Ceres are also block oriented. When
@@ -229,7 +235,6 @@
   // ordering.
   bool ApproximateMinimumDegreeOrdering(cholmod_sparse* matrix, int* ordering);
 
-
   // Before SuiteSparse version 4.2.0, cholmod_camd was only enabled
   // if SuiteSparse was compiled with Metis support. This makes
   // calling and linking into cholmod_camd problematic even though it
@@ -262,7 +267,7 @@
                                                    int* ordering);
 
   void Free(cholmod_sparse* m) { cholmod_free_sparse(&m, &cc_); }
-  void Free(cholmod_dense* m)  { cholmod_free_dense(&m, &cc_);  }
+  void Free(cholmod_dense* m) { cholmod_free_dense(&m, &cc_); }
   void Free(cholmod_factor* m) { cholmod_free_factor(&m, &cc_); }
 
   void Print(cholmod_sparse* m, const std::string& name) {
@@ -285,17 +290,17 @@
 
 class SuiteSparseCholesky : public SparseCholesky {
  public:
-  static std::unique_ptr<SparseCholesky> Create(
-      OrderingType ordering_type);
+  static std::unique_ptr<SparseCholesky> Create(OrderingType ordering_type);
 
   // SparseCholesky interface.
   virtual ~SuiteSparseCholesky();
-  virtual CompressedRowSparseMatrix::StorageType StorageType() const;
-  virtual LinearSolverTerminationType Factorize(
-      CompressedRowSparseMatrix* lhs, std::string* message);
-  virtual LinearSolverTerminationType Solve(const double* rhs,
-                                            double* solution,
-                                            std::string* message);
+  CompressedRowSparseMatrix::StorageType StorageType() const final;
+  LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
+                                        std::string* message) final;
+  LinearSolverTerminationType Solve(const double* rhs,
+                                    double* solution,
+                                    std::string* message) final;
+
  private:
   SuiteSparseCholesky(const OrderingType ordering_type);
 
diff --git a/internal/ceres/system_test.cc b/internal/ceres/system_test.cc
index 3f635d0..429973f 100644
--- a/internal/ceres/system_test.cc
+++ b/internal/ceres/system_test.cc
@@ -64,10 +64,10 @@
 class PowellsFunction {
  public:
   PowellsFunction() {
-    x_[0] =  3.0;
+    x_[0] = 3.0;
     x_[1] = -1.0;
-    x_[2] =  0.0;
-    x_[3] =  1.0;
+    x_[2] = 0.0;
+    x_[3] = 1.0;
 
     problem_.AddResidualBlock(
         new AutoDiffCostFunction<F1, 1, 1, 1>(new F1), NULL, &x_[0], &x_[1]);
@@ -94,9 +94,8 @@
   // functions.
   class F1 {
    public:
-    template <typename T> bool operator()(const T* const x1,
-                                          const T* const x2,
-                                          T* residual) const {
+    template <typename T>
+    bool operator()(const T* const x1, const T* const x2, T* residual) const {
       // f1 = x1 + 10 * x2;
       *residual = *x1 + 10.0 * *x2;
       return true;
@@ -105,9 +104,8 @@
 
   class F2 {
    public:
-    template <typename T> bool operator()(const T* const x3,
-                                          const T* const x4,
-                                          T* residual) const {
+    template <typename T>
+    bool operator()(const T* const x3, const T* const x4, T* residual) const {
       // f2 = sqrt(5) (x3 - x4)
       *residual = sqrt(5.0) * (*x3 - *x4);
       return true;
@@ -116,9 +114,8 @@
 
   class F3 {
    public:
-    template <typename T> bool operator()(const T* const x2,
-                                          const T* const x4,
-                                          T* residual) const {
+    template <typename T>
+    bool operator()(const T* const x2, const T* const x4, T* residual) const {
       // f3 = (x2 - 2 x3)^2
       residual[0] = (x2[0] - 2.0 * x4[0]) * (x2[0] - 2.0 * x4[0]);
       return true;
@@ -127,9 +124,8 @@
 
   class F4 {
    public:
-    template <typename T> bool operator()(const T* const x1,
-                                          const T* const x4,
-                                          T* residual) const {
+    template <typename T>
+    bool operator()(const T* const x1, const T* const x4, T* residual) const {
       // f4 = sqrt(10) (x1 - x4)^2
       residual[0] = sqrt(10.0) * (x1[0] - x4[0]) * (x1[0] - x4[0]);
       return true;
diff --git a/internal/ceres/test_util.cc b/internal/ceres/test_util.cc
index 5156856..a131b79 100644
--- a/internal/ceres/test_util.cc
+++ b/internal/ceres/test_util.cc
@@ -34,6 +34,7 @@
 
 #include <algorithm>
 #include <cmath>
+
 #include "ceres/file.h"
 #include "ceres/stringprintf.h"
 #include "ceres/types.h"
@@ -54,6 +55,15 @@
 namespace internal {
 
 bool ExpectClose(double x, double y, double max_abs_relative_difference) {
+  if (std::isinf(x) && std::isinf(y)) {
+    EXPECT_EQ(std::signbit(x), std::signbit(y));
+    return true;
+  }
+
+  if (std::isnan(x) && std::isnan(y)) {
+    return true;
+  }
+
   double absolute_difference = fabs(x - y);
   double relative_difference = absolute_difference / std::max(fabs(x), fabs(y));
   if (x == 0 || y == 0) {
@@ -63,7 +73,10 @@
   }
   if (relative_difference > max_abs_relative_difference) {
     VLOG(1) << StringPrintf("x=%17g y=%17g abs=%17g rel=%17g",
-                            x, y, absolute_difference, relative_difference);
+                            x,
+                            y,
+                            absolute_difference,
+                            relative_difference);
   }
 
   EXPECT_NEAR(relative_difference, 0.0, max_abs_relative_difference);
@@ -108,36 +121,30 @@
   }
 }
 
-void ExpectArraysClose(int n,
-                       const double* p,
-                       const double* q,
-                       double tol) {
+void ExpectArraysClose(int n, const double* p, const double* q, double tol) {
   CHECK_GT(n, 0);
   CHECK(p);
   CHECK(q);
 
   for (int i = 0; i < n; ++i) {
-    EXPECT_TRUE(ExpectClose(p[i], q[i], tol))
-        << "p[" << i << "]" << p[i] << " "
-        << "q[" << i << "]" << q[i] << " "
-        << "tol: " << tol;
+    EXPECT_TRUE(ExpectClose(p[i], q[i], tol)) << "p[" << i << "]" << p[i] << " "
+                                              << "q[" << i << "]" << q[i] << " "
+                                              << "tol: " << tol;
   }
 }
 
 std::string TestFileAbsolutePath(const std::string& filename) {
-  return JoinPath(FLAGS_test_srcdir + CERES_TEST_SRCDIR_SUFFIX,
-                  filename);
+  return JoinPath(FLAGS_test_srcdir + CERES_TEST_SRCDIR_SUFFIX, filename);
 }
 
 std::string ToString(const Solver::Options& options) {
-  return StringPrintf(
-      "(%s, %s, %s, %s, %d)",
-      LinearSolverTypeToString(options.linear_solver_type),
-      SparseLinearAlgebraLibraryTypeToString(
-          options.sparse_linear_algebra_library_type),
-      options.linear_solver_ordering? "USER": "AUTOMATIC",
-      PreconditionerTypeToString(options.preconditioner_type),
-      options.num_threads);
+  return StringPrintf("(%s, %s, %s, %s, %d)",
+                      LinearSolverTypeToString(options.linear_solver_type),
+                      SparseLinearAlgebraLibraryTypeToString(
+                          options.sparse_linear_algebra_library_type),
+                      options.linear_solver_ordering ? "USER" : "AUTOMATIC",
+                      PreconditionerTypeToString(options.preconditioner_type),
+                      options.num_threads);
 }
 
 }  // namespace internal
diff --git a/internal/ceres/test_util.h b/internal/ceres/test_util.h
index e43eb35..c33c69c 100644
--- a/internal/ceres/test_util.h
+++ b/internal/ceres/test_util.h
@@ -32,6 +32,7 @@
 #define CERES_INTERNAL_TEST_UTIL_H_
 
 #include <string>
+
 #include "ceres/internal/port.h"
 #include "ceres/problem.h"
 #include "ceres/solver.h"
@@ -44,15 +45,20 @@
 // Expects that x and y have a relative difference of no more than
 // max_abs_relative_difference. If either x or y is zero, then the relative
 // difference is interpreted as an absolute difference.
-bool ExpectClose(double x, double y, double max_abs_relative_difference);
+//
+// If x and y have the same non-finite value (inf or nan) we treat them as being
+// close. In such a case no error is thrown and true is returned.
+CERES_EXPORT_INTERNAL bool ExpectClose(double x,
+                                       double y,
+                                       double max_abs_relative_difference);
 
 // Expects that for all i = 1,.., n - 1
 //
 //   |p[i] - q[i]| / max(|p[i]|, |q[i]|) < tolerance
-void ExpectArraysClose(int n,
-                       const double* p,
-                       const double* q,
-                       double tolerance);
+CERES_EXPORT_INTERNAL void ExpectArraysClose(int n,
+                                             const double* p,
+                                             const double* q,
+                                             double tolerance);
 
 // Expects that for all i = 1,.., n - 1
 //
@@ -60,16 +66,17 @@
 //
 // where max_norm_p and max_norm_q are the max norms of the arrays p
 // and q respectively.
-void ExpectArraysCloseUptoScale(int n,
-                                const double* p,
-                                const double* q,
-                                double tolerance);
+CERES_EXPORT_INTERNAL void ExpectArraysCloseUptoScale(int n,
+                                                      const double* p,
+                                                      const double* q,
+                                                      double tolerance);
 
 // Construct a fully qualified path for the test file depending on the
 // local build/testing environment.
-std::string TestFileAbsolutePath(const std::string& filename);
+CERES_EXPORT_INTERNAL std::string TestFileAbsolutePath(
+    const std::string& filename);
 
-std::string ToString(const Solver::Options& options);
+CERES_EXPORT_INTERNAL std::string ToString(const Solver::Options& options);
 
 // A templated test fixture, that is used for testing Ceres end to end
 // by computing a solution to the problem for a given solver
@@ -80,7 +87,7 @@
 template <typename SystemTestProblem>
 class SystemTest : public ::testing::Test {
  protected:
-  virtual void SetUp() {
+  void SetUp() final {
     SystemTestProblem system_test_problem;
     SolveAndEvaluateFinalResiduals(
         *system_test_problem.mutable_solver_options(),
@@ -113,11 +120,8 @@
     Solver::Summary summary;
     Solve(options, problem, &summary);
     CHECK_NE(summary.termination_type, ceres::FAILURE);
-    problem->Evaluate(Problem::EvaluateOptions(),
-                      nullptr,
-                      final_residuals,
-                      nullptr,
-                      nullptr);
+    problem->Evaluate(
+        Problem::EvaluateOptions(), nullptr, final_residuals, nullptr, nullptr);
   }
 
   std::vector<double> expected_final_residuals_;
diff --git a/internal/ceres/thread_pool.cc b/internal/ceres/thread_pool.cc
index 991da30..821431c 100644
--- a/internal/ceres/thread_pool.cc
+++ b/internal/ceres/thread_pool.cc
@@ -31,13 +31,13 @@
 // This include must come before any #ifndef check on Ceres compile options.
 #include "ceres/internal/port.h"
 
-#ifdef CERES_USE_CXX11_THREADS
-
-#include "ceres/thread_pool.h"
+#ifdef CERES_USE_CXX_THREADS
 
 #include <cmath>
 #include <limits>
 
+#include "ceres/thread_pool.h"
+
 namespace ceres {
 namespace internal {
 namespace {
@@ -53,16 +53,13 @@
   const int num_hardware_threads = std::thread::hardware_concurrency();
   // hardware_concurrency() can return 0 if the value is not well defined or not
   // computable.
-  return num_hardware_threads == 0
-      ? std::numeric_limits<int>::max()
-      : num_hardware_threads;
+  return num_hardware_threads == 0 ? std::numeric_limits<int>::max()
+                                   : num_hardware_threads;
 }
 
-ThreadPool::ThreadPool() { }
+ThreadPool::ThreadPool() {}
 
-ThreadPool::ThreadPool(int num_threads) {
-  Resize(num_threads);
-}
+ThreadPool::ThreadPool(int num_threads) { Resize(num_threads); }
 
 ThreadPool::~ThreadPool() {
   std::lock_guard<std::mutex> lock(thread_pool_mutex_);
@@ -106,11 +103,9 @@
   }
 }
 
-void ThreadPool::Stop() {
-  task_queue_.StopWaiters();
-}
+void ThreadPool::Stop() { task_queue_.StopWaiters(); }
 
 }  // namespace internal
 }  // namespace ceres
 
-#endif // CERES_USE_CXX11_THREADS
+#endif  // CERES_USE_CXX_THREADS
diff --git a/internal/ceres/thread_pool.h b/internal/ceres/thread_pool.h
index 1ebb52e..cdf6625 100644
--- a/internal/ceres/thread_pool.h
+++ b/internal/ceres/thread_pool.h
@@ -37,6 +37,7 @@
 #include <vector>
 
 #include "ceres/concurrent_queue.h"
+#include "ceres/internal/port.h"
 
 namespace ceres {
 namespace internal {
@@ -57,7 +58,7 @@
 //  workers to stop.  The workers will finish all of the tasks that have already
 //  been added to the thread pool.
 //
-class ThreadPool {
+class CERES_EXPORT_INTERNAL ThreadPool {
  public:
   // Returns the maximum number of hardware threads.
   static int MaxNumThreadsAvailable();
diff --git a/internal/ceres/thread_pool_test.cc b/internal/ceres/thread_pool_test.cc
index 2b1bf87..e39f673 100644
--- a/internal/ceres/thread_pool_test.cc
+++ b/internal/ceres/thread_pool_test.cc
@@ -31,18 +31,17 @@
 // This include must come before any #ifndef check on Ceres compile options.
 #include "ceres/internal/port.h"
 
-#ifdef CERES_USE_CXX11_THREADS
-
-#include "ceres/thread_pool.h"
+#ifdef CERES_USE_CXX_THREADS
 
 #include <chrono>
 #include <condition_variable>
 #include <mutex>
 #include <thread>
 
+#include "ceres/thread_pool.h"
+#include "glog/logging.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "glog/logging.h"
 
 namespace ceres {
 namespace internal {
@@ -59,14 +58,14 @@
 
     for (int i = 0; i < num_tasks; ++i) {
       thread_pool.AddTask([&]() {
-          std::lock_guard<std::mutex> lock(mutex);
-          ++value;
-          condition.notify_all();
-        });
+        std::lock_guard<std::mutex> lock(mutex);
+        ++value;
+        condition.notify_all();
+      });
     }
 
     std::unique_lock<std::mutex> lock(mutex);
-    condition.wait(lock, [&](){return value == num_tasks;});
+    condition.wait(lock, [&]() { return value == num_tasks; });
   }
 
   EXPECT_EQ(num_tasks, value);
@@ -116,7 +115,7 @@
 
     // Unlock the mutex to unblock all of the threads and wait until all of the
     // tasks are completed.
-    condition.wait(lock, [&](){return value == num_tasks;});
+    condition.wait(lock, [&]() { return value == num_tasks; });
   }
 
   EXPECT_EQ(num_tasks, value);
@@ -197,4 +196,4 @@
 }  // namespace internal
 }  // namespace ceres
 
-#endif // CERES_USE_CXX11_THREADS
+#endif  // CERES_USE_CXX_THREADS
diff --git a/internal/ceres/thread_token_provider.cc b/internal/ceres/thread_token_provider.cc
index 337217b..c7ec67f 100644
--- a/internal/ceres/thread_token_provider.cc
+++ b/internal/ceres/thread_token_provider.cc
@@ -39,12 +39,11 @@
 
 ThreadTokenProvider::ThreadTokenProvider(int num_threads) {
   (void)num_threads;
-#ifdef CERES_USE_CXX11_THREADS
+#ifdef CERES_USE_CXX_THREADS
   for (int i = 0; i < num_threads; i++) {
     pool_.Push(i);
   }
 #endif
-
 }
 
 int ThreadTokenProvider::Acquire() {
@@ -56,20 +55,18 @@
   return 0;
 #endif
 
-#ifdef CERES_USE_CXX11_THREADS
+#ifdef CERES_USE_CXX_THREADS
   int thread_id;
   CHECK(pool_.Wait(&thread_id));
   return thread_id;
 #endif
-
 }
 
 void ThreadTokenProvider::Release(int thread_id) {
   (void)thread_id;
-#ifdef CERES_USE_CXX11_THREADS
+#ifdef CERES_USE_CXX_THREADS
   pool_.Push(thread_id);
 #endif
-
 }
 
 }  // namespace internal
diff --git a/internal/ceres/thread_token_provider.h b/internal/ceres/thread_token_provider.h
index f6298b7..06dc043 100644
--- a/internal/ceres/thread_token_provider.h
+++ b/internal/ceres/thread_token_provider.h
@@ -34,15 +34,15 @@
 #include "ceres/internal/config.h"
 #include "ceres/internal/port.h"
 
-#ifdef CERES_USE_CXX11_THREADS
+#ifdef CERES_USE_CXX_THREADS
 #include "ceres/concurrent_queue.h"
 #endif
 
 namespace ceres {
 namespace internal {
 
-// Helper for C++11 thread number identification that is similar to
-// omp_get_thread_num() behaviour. This is necessary to support C++11
+// Helper for C++ thread number identification that is similar to
+// omp_get_thread_num() behaviour. This is necessary to support C++
 // threading with a sequential thread id. This is used to access preallocated
 // resources in the parallelized code parts.  The sequence of tokens varies from
 // 0 to num_threads - 1 that can be acquired to identify the thread in a thread
@@ -78,7 +78,7 @@
   void Release(int thread_id);
 
  private:
-#ifdef CERES_USE_CXX11_THREADS
+#ifdef CERES_USE_CXX_THREADS
   // This queue initially holds a sequence from 0..num_threads-1. Every
   // Acquire() call the first number is removed from here. When the token is not
   // needed anymore it shall be given back with corresponding Release()
diff --git a/internal/ceres/tiny_solver_autodiff_function_test.cc b/internal/ceres/tiny_solver_autodiff_function_test.cc
index 90033fc..2598188 100644
--- a/internal/ceres/tiny_solver_autodiff_function_test.cc
+++ b/internal/ceres/tiny_solver_autodiff_function_test.cc
@@ -30,27 +30,27 @@
 // Author: mierle@gmail.com (Keir Mierle)
 
 #include "ceres/tiny_solver_autodiff_function.h"
-#include "ceres/tiny_solver.h"
-#include "ceres/tiny_solver_test_util.h"
 
 #include <algorithm>
 #include <cmath>
 #include <limits>
 
+#include "ceres/tiny_solver.h"
+#include "ceres/tiny_solver_test_util.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
 
 struct AutoDiffTestFunctor {
-  template<typename T>
+  template <typename T>
   bool operator()(const T* const parameters, T* residuals) const {
     // Shift the parameters so the solution is not at the origin, to prevent
     // accidentally showing "PASS".
     const T& a = parameters[0] - T(1.0);
     const T& b = parameters[1] - T(2.0);
     const T& c = parameters[2] - T(3.0);
-    residuals[0] = 2.*a + 0.*b + 1.*c;
-    residuals[1] = 0.*a + 4.*b + 6.*c;
+    residuals[0] = 2. * a + 0. * b + 1. * c;
+    residuals[1] = 0. * a + 4. * b + 6. * c;
     return true;
   }
 };
@@ -103,11 +103,9 @@
     NUM_PARAMETERS = 3,
   };
 
-  int NumResiduals() const {
-    return 2;
-  }
+  int NumResiduals() const { return 2; }
 
-  template<typename T>
+  template <typename T>
   bool operator()(const T* parameters, T* residuals) const {
     // Jacobian is not evaluated by cost function, but by autodiff.
     T* jacobian = nullptr;
@@ -115,7 +113,7 @@
   }
 };
 
-template<typename Function, typename Vector>
+template <typename Function, typename Vector>
 void TestHelper(const Function& f, const Vector& x0) {
   Vector x = x0;
   Eigen::Vector2d residuals;
@@ -133,10 +131,8 @@
   Eigen::Vector3d x0(0.76026643, -30.01799744, 0.55192142);
 
   DynamicResidualsFunctor f;
-  using AutoDiffCostFunctor =
-      ceres::TinySolverAutoDiffFunction<DynamicResidualsFunctor,
-                                        Eigen::Dynamic,
-                                        3>;
+  using AutoDiffCostFunctor = ceres::
+      TinySolverAutoDiffFunction<DynamicResidualsFunctor, Eigen::Dynamic, 3>;
   AutoDiffCostFunctor f_autodiff(f);
 
   Eigen::Vector2d residuals;
diff --git a/internal/ceres/tiny_solver_cost_function_adapter_test.cc b/internal/ceres/tiny_solver_cost_function_adapter_test.cc
index 620df41..6f57193 100644
--- a/internal/ceres/tiny_solver_cost_function_adapter_test.cc
+++ b/internal/ceres/tiny_solver_cost_function_adapter_test.cc
@@ -40,15 +40,15 @@
 
 namespace ceres {
 
-class CostFunction2x3 : public SizedCostFunction<2,3> {
-  virtual bool Evaluate(double const* const* parameters,
-                        double* residuals,
-                        double** jacobians) const {
+class CostFunction2x3 : public SizedCostFunction<2, 3> {
+  bool Evaluate(double const* const* parameters,
+                double* residuals,
+                double** jacobians) const final {
     double x = parameters[0][0];
     double y = parameters[0][1];
     double z = parameters[0][2];
 
-    residuals[0] = x + 2*y + 4*z;
+    residuals[0] = x + 2 * y + 4 * z;
     residuals[1] = y * z;
 
     if (jacobians && jacobians[0]) {
@@ -65,10 +65,11 @@
   }
 };
 
-template<int kNumResiduals, int kNumParameters>
+template <int kNumResiduals, int kNumParameters>
 void TestHelper() {
   std::unique_ptr<CostFunction> cost_function(new CostFunction2x3);
-  typedef  TinySolverCostFunctionAdapter<kNumResiduals, kNumParameters> CostFunctionAdapter;
+  typedef TinySolverCostFunctionAdapter<kNumResiduals, kNumParameters>
+      CostFunctionAdapter;
   CostFunctionAdapter cfa(*cost_function);
   EXPECT_EQ(CostFunctionAdapter::NUM_RESIDUALS, kNumResiduals);
   EXPECT_EQ(CostFunctionAdapter::NUM_PARAMETERS, kNumParameters);
@@ -80,7 +81,7 @@
   Eigen::Matrix<double, 2, 3, Eigen::ColMajor> actual_jacobian;
   Eigen::Matrix<double, 2, 3, Eigen::RowMajor> expected_jacobian;
 
-  double xyz[3] = { 1.0, -1.0, 2.0};
+  double xyz[3] = {1.0, -1.0, 2.0};
   double* parameters[1] = {xyz};
 
   // Check that residual only evaluation works.
diff --git a/internal/ceres/tiny_solver_test.cc b/internal/ceres/tiny_solver_test.cc
index 2a8cd39..2e70694 100644
--- a/internal/ceres/tiny_solver_test.cc
+++ b/internal/ceres/tiny_solver_test.cc
@@ -30,11 +30,11 @@
 // Author: mierle@gmail.com (Keir Mierle)
 
 #include "ceres/tiny_solver.h"
-#include "ceres/tiny_solver_test_util.h"
 
 #include <algorithm>
 #include <cmath>
 
+#include "ceres/tiny_solver_test_util.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -66,9 +66,7 @@
     NUM_PARAMETERS = Eigen::Dynamic,
   };
 
-  int NumParameters() const {
-    return 3;
-  }
+  int NumParameters() const { return 3; }
 
   bool operator()(const double* parameters,
                   double* residuals,
@@ -85,9 +83,7 @@
     NUM_PARAMETERS = 3,
   };
 
-  int NumResiduals() const {
-    return 2;
-  }
+  int NumResiduals() const { return 2; }
 
   bool operator()(const double* parameters,
                   double* residuals,
@@ -104,13 +100,9 @@
     NUM_PARAMETERS = Eigen::Dynamic,
   };
 
-  int NumResiduals() const {
-    return 2;
-  }
+  int NumResiduals() const { return 2; }
 
-  int NumParameters() const {
-    return 3;
-  }
+  int NumParameters() const { return 3; }
 
   bool operator()(const double* parameters,
                   double* residuals,
@@ -119,7 +111,7 @@
   }
 };
 
-template<typename Function, typename Vector>
+template <typename Function, typename Vector>
 void TestHelper(const Function& f, const Vector& x0) {
   Vector x = x0;
   Vec2 residuals;
diff --git a/internal/ceres/tiny_solver_test_util.h b/internal/ceres/tiny_solver_test_util.h
index 48fe955..310bb35 100644
--- a/internal/ceres/tiny_solver_test_util.h
+++ b/internal/ceres/tiny_solver_test_util.h
@@ -34,7 +34,7 @@
 
 namespace ceres {
 
-template<typename T>
+template <typename T>
 bool EvaluateResidualsAndJacobians(const T* parameters,
                                    T* residuals,
                                    T* jacobian) {
diff --git a/internal/ceres/triplet_sparse_matrix.cc b/internal/ceres/triplet_sparse_matrix.cc
index 15b9674..5dbf0e7 100644
--- a/internal/ceres/triplet_sparse_matrix.cc
+++ b/internal/ceres/triplet_sparse_matrix.cc
@@ -43,11 +43,7 @@
 namespace internal {
 
 TripletSparseMatrix::TripletSparseMatrix()
-    : num_rows_(0),
-      num_cols_(0),
-      max_num_nonzeros_(0),
-      num_nonzeros_(0) {}
-
+    : num_rows_(0), num_cols_(0), max_num_nonzeros_(0), num_nonzeros_(0) {}
 
 TripletSparseMatrix::~TripletSparseMatrix() {}
 
@@ -97,6 +93,9 @@
 
 TripletSparseMatrix& TripletSparseMatrix::operator=(
     const TripletSparseMatrix& rhs) {
+  if (this == &rhs) {
+    return *this;
+  }
   num_rows_ = rhs.num_rows_;
   num_cols_ = rhs.num_cols_;
   num_nonzeros_ = rhs.num_nonzeros_;
@@ -108,9 +107,11 @@
 
 bool TripletSparseMatrix::AllTripletsWithinBounds() const {
   for (int i = 0; i < num_nonzeros_; ++i) {
+    // clang-format off
     if ((rows_[i] < 0) || (rows_[i] >= num_rows_) ||
         (cols_[i] < 0) || (cols_[i] >= num_cols_))
       return false;
+    // clang-format on
   }
   return true;
 }
@@ -120,8 +121,7 @@
       << "Reallocation will cause data loss";
 
   // Nothing to do if we have enough space already.
-  if (new_max_num_nonzeros <= max_num_nonzeros_)
-    return;
+  if (new_max_num_nonzeros <= max_num_nonzeros_) return;
 
   int* new_rows = new int[new_max_num_nonzeros];
   int* new_cols = new int[new_max_num_nonzeros];
@@ -165,15 +165,15 @@
   }
 }
 
-void TripletSparseMatrix::RightMultiply(const double* x,  double* y) const {
+void TripletSparseMatrix::RightMultiply(const double* x, double* y) const {
   for (int i = 0; i < num_nonzeros_; ++i) {
-    y[rows_[i]] += values_[i]*x[cols_[i]];
+    y[rows_[i]] += values_[i] * x[cols_[i]];
   }
 }
 
 void TripletSparseMatrix::LeftMultiply(const double* x, double* y) const {
   for (int i = 0; i < num_nonzeros_; ++i) {
-    y[cols_[i]] += values_[i]*x[rows_[i]];
+    y[cols_[i]] += values_[i] * x[rows_[i]];
   }
 }
 
@@ -223,10 +223,9 @@
   num_cols_ = num_cols_ + B.num_cols();
 }
 
-
 void TripletSparseMatrix::Resize(int new_num_rows, int new_num_cols) {
   if ((new_num_rows >= num_rows_) && (new_num_cols >= num_cols_)) {
-    num_rows_  = new_num_rows;
+    num_rows_ = new_num_rows;
     num_cols_ = new_num_cols;
     return;
   }
@@ -242,9 +241,9 @@
   for (int i = 0; i < num_nonzeros_; ++i) {
     if ((r_ptr[i] < num_rows_) && (c_ptr[i] < num_cols_)) {
       if (dropped_terms) {
-        r_ptr[i-dropped_terms] = r_ptr[i];
-        c_ptr[i-dropped_terms] = c_ptr[i];
-        v_ptr[i-dropped_terms] = v_ptr[i];
+        r_ptr[i - dropped_terms] = r_ptr[i];
+        c_ptr[i - dropped_terms] = c_ptr[i];
+        v_ptr[i - dropped_terms] = v_ptr[i];
       }
     } else {
       ++dropped_terms;
diff --git a/internal/ceres/triplet_sparse_matrix.h b/internal/ceres/triplet_sparse_matrix.h
index 606f8e8..cc9fee5 100644
--- a/internal/ceres/triplet_sparse_matrix.h
+++ b/internal/ceres/triplet_sparse_matrix.h
@@ -33,8 +33,10 @@
 
 #include <memory>
 #include <vector>
-#include "ceres/sparse_matrix.h"
+
 #include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
+#include "ceres/sparse_matrix.h"
 #include "ceres/types.h"
 
 namespace ceres {
@@ -44,7 +46,7 @@
 // manipulate sparse matrices in triplet (i,j,s) form.  This object is
 // inspired by the design of the cholmod_triplet struct used in the
 // SuiteSparse package and is memory layout compatible with it.
-class TripletSparseMatrix : public SparseMatrix {
+class CERES_EXPORT_INTERNAL TripletSparseMatrix : public SparseMatrix {
  public:
   TripletSparseMatrix();
   TripletSparseMatrix(int num_rows, int num_cols, int max_num_nonzeros);
@@ -58,22 +60,24 @@
 
   TripletSparseMatrix& operator=(const TripletSparseMatrix& rhs);
 
-  ~TripletSparseMatrix();
+  virtual ~TripletSparseMatrix();
 
   // Implementation of the SparseMatrix interface.
-  virtual void SetZero();
-  virtual void RightMultiply(const double* x, double* y) const;
-  virtual void LeftMultiply(const double* x, double* y) const;
-  virtual void SquaredColumnNorm(double* x) const;
-  virtual void ScaleColumns(const double* scale);
-  virtual void ToDenseMatrix(Matrix* dense_matrix) const;
-  virtual void ToTextFile(FILE* file) const;
-  virtual int num_rows()        const { return num_rows_;     }
-  virtual int num_cols()        const { return num_cols_;     }
-  virtual int num_nonzeros()    const { return num_nonzeros_; }
-  virtual const double* values()  const { return values_.get(); }
-  virtual double* mutable_values()      { return values_.get(); }
-  virtual void set_num_nonzeros(int num_nonzeros);
+  void SetZero() final;
+  void RightMultiply(const double* x, double* y) const final;
+  void LeftMultiply(const double* x, double* y) const final;
+  void SquaredColumnNorm(double* x) const final;
+  void ScaleColumns(const double* scale) final;
+  void ToDenseMatrix(Matrix* dense_matrix) const final;
+  void ToTextFile(FILE* file) const final;
+  // clang-format off
+  int num_rows()        const final   { return num_rows_;     }
+  int num_cols()        const final   { return num_cols_;     }
+  int num_nonzeros()    const final   { return num_nonzeros_; }
+  const double* values()  const final { return values_.get(); }
+  double* mutable_values() final      { return values_.get(); }
+  // clang-format on
+  void set_num_nonzeros(int num_nonzeros);
 
   // Increase max_num_nonzeros and correspondingly increase the size
   // of rows_, cols_ and values_. If new_max_num_nonzeros is smaller
@@ -94,11 +98,13 @@
   // bounds are dropped and the num_non_zeros changed accordingly.
   void Resize(int new_num_rows, int new_num_cols);
 
+  // clang-format off
   int max_num_nonzeros() const { return max_num_nonzeros_; }
   const int* rows()      const { return rows_.get();       }
   const int* cols()      const { return cols_.get();       }
   int* mutable_rows()          { return rows_.get();       }
   int* mutable_cols()          { return cols_.get();       }
+  // clang-format on
 
   // Returns true if the entries of the matrix obey the row, column,
   // and column size bounds and false otherwise.
diff --git a/internal/ceres/triplet_sparse_matrix_test.cc b/internal/ceres/triplet_sparse_matrix_test.cc
index d71df7b..3af634f 100644
--- a/internal/ceres/triplet_sparse_matrix_test.cc
+++ b/internal/ceres/triplet_sparse_matrix_test.cc
@@ -31,6 +31,7 @@
 #include "ceres/triplet_sparse_matrix.h"
 
 #include <memory>
+
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -172,6 +173,35 @@
   EXPECT_DOUBLE_EQ(cpy.values()[1], 5.2);
 }
 
+TEST(TripletSparseMatrix, AssignmentOperatorSelfAssignment) {
+  TripletSparseMatrix orig(2, 5, 4);
+  orig.mutable_rows()[0] = 0;
+  orig.mutable_cols()[0] = 1;
+  orig.mutable_values()[0] = 2.5;
+
+  orig.mutable_rows()[1] = 1;
+  orig.mutable_cols()[1] = 4;
+  orig.mutable_values()[1] = 5.2;
+  orig.set_num_nonzeros(2);
+
+  // Who's on earth gonna do this?
+  orig = orig;
+
+  EXPECT_EQ(orig.num_rows(), 2);
+  EXPECT_EQ(orig.num_cols(), 5);
+  ASSERT_EQ(orig.num_nonzeros(), 2);
+  EXPECT_EQ(orig.max_num_nonzeros(), 4);
+
+  EXPECT_EQ(orig.rows()[0], 0);
+  EXPECT_EQ(orig.rows()[1], 1);
+
+  EXPECT_EQ(orig.cols()[0], 1);
+  EXPECT_EQ(orig.cols()[1], 4);
+
+  EXPECT_DOUBLE_EQ(orig.values()[0], 2.5);
+  EXPECT_DOUBLE_EQ(orig.values()[1], 5.2);
+}
+
 TEST(TripletSparseMatrix, AppendRows) {
   // Build one matrix.
   TripletSparseMatrix m(2, 5, 4);
@@ -280,15 +310,14 @@
 
 TEST(TripletSparseMatrix, CreateDiagonalMatrix) {
   std::unique_ptr<double[]> values(new double[10]);
-  for (int i = 0; i < 10; ++i)
-    values[i] = i;
+  for (int i = 0; i < 10; ++i) values[i] = i;
 
   std::unique_ptr<TripletSparseMatrix> m(
       TripletSparseMatrix::CreateSparseDiagonalMatrix(values.get(), 10));
   EXPECT_EQ(m->num_rows(), 10);
   EXPECT_EQ(m->num_cols(), 10);
   ASSERT_EQ(m->num_nonzeros(), 10);
-  for (int i = 0; i < 10 ; ++i) {
+  for (int i = 0; i < 10; ++i) {
     EXPECT_EQ(m->rows()[i], i);
     EXPECT_EQ(m->cols()[i], i);
     EXPECT_EQ(m->values()[i], i);
@@ -302,7 +331,7 @@
     for (int j = 0; j < 20; ++j) {
       m.mutable_rows()[nnz] = i;
       m.mutable_cols()[nnz] = j;
-      m.mutable_values()[nnz++] = i+j;
+      m.mutable_values()[nnz++] = i + j;
     }
   }
   m.set_num_nonzeros(nnz);
diff --git a/internal/ceres/trust_region_minimizer.cc b/internal/ceres/trust_region_minimizer.cc
index 5505cbb..bcf05b3 100644
--- a/internal/ceres/trust_region_minimizer.cc
+++ b/internal/ceres/trust_region_minimizer.cc
@@ -34,8 +34,8 @@
 #include <cmath>
 #include <cstdlib>
 #include <cstring>
-#include <memory>
 #include <limits>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -83,6 +83,11 @@
 
   while (FinalizeIterationAndCheckIfMinimizerCanContinue()) {
     iteration_start_time_in_secs_ = WallTimeInSeconds();
+
+    const double previous_gradient_norm = iteration_summary_.gradient_norm;
+    const double previous_gradient_max_norm =
+        iteration_summary_.gradient_max_norm;
+
     iteration_summary_ = IterationSummary();
     iteration_summary_.iteration =
         solver_summary->iterations.back().iteration + 1;
@@ -93,7 +98,8 @@
       continue;
     }
 
-    if (options_.is_constrained) {
+    if (options_.is_constrained &&
+        options_.max_num_line_search_step_size_iterations > 0) {
       // Use a projected line search to enforce the bounds constraints
       // and improve the quality of the step.
       DoLineSearch(x_, gradient_, x_cost_, &delta_);
@@ -112,10 +118,18 @@
 
     if (IsStepSuccessful()) {
       RETURN_IF_ERROR_AND_LOG(HandleSuccessfulStep());
-      continue;
-    }
+    } else {
+      // Declare the step unsuccessful and inform the trust region strategy.
+      iteration_summary_.step_is_successful = false;
+      iteration_summary_.cost = candidate_cost_ + solver_summary_->fixed_cost;
 
-    HandleUnsuccessfulStep();
+      // When the step is unsuccessful, we do not compute the gradient
+      // (or update x), so we preserve its value from the last
+      // successful iteration.
+      iteration_summary_.gradient_norm = previous_gradient_norm;
+      iteration_summary_.gradient_max_norm = previous_gradient_max_norm;
+      strategy_->StepRejected(iteration_summary_.relative_decrease);
+    }
   }
 }
 
@@ -145,7 +159,7 @@
 
   is_not_silent_ = !options.is_silent;
   inner_iterations_are_enabled_ =
-      options.inner_iteration_minimizer.get() != NULL;
+      options.inner_iteration_minimizer.get() != nullptr;
   inner_iterations_were_useful_ = false;
 
   num_parameters_ = evaluator_->NumParameters();
@@ -424,10 +438,12 @@
     num_consecutive_invalid_steps_ = 0;
   }
 
-  VLOG_IF(1, is_not_silent_ && !iteration_summary_.step_is_valid)
-      << "Invalid step: current_cost: " << x_cost_
-      << " absolute model cost change: " << model_cost_change_
-      << " relative model cost change: " << (model_cost_change_ / x_cost_);
+  if (is_not_silent_ && !iteration_summary_.step_is_valid) {
+    VLOG(1) << "Invalid step: current_cost: " << x_cost_
+            << " absolute model cost change: " << model_cost_change_
+            << " relative model cost change: "
+            << (model_cost_change_ / x_cost_);
+  }
   return true;
 }
 
@@ -490,17 +506,22 @@
   options_.inner_iteration_minimizer->Minimize(
       options_, inner_iteration_x_.data(), &inner_iteration_summary);
   double inner_iteration_cost;
-  if (!evaluator_->Evaluate(
-          inner_iteration_x_.data(), &inner_iteration_cost, NULL, NULL, NULL)) {
-    VLOG_IF(2, is_not_silent_) << "Inner iteration failed.";
+  if (!evaluator_->Evaluate(inner_iteration_x_.data(),
+                            &inner_iteration_cost,
+                            nullptr,
+                            nullptr,
+                            nullptr)) {
+    if (is_not_silent_) {
+      VLOG(2) << "Inner iteration failed.";
+    }
     return;
   }
 
-  VLOG_IF(2, is_not_silent_)
-      << "Inner iteration succeeded; Current cost: " << x_cost_
-      << " Trust region step cost: " << candidate_cost_
-      << " Inner iteration cost: " << inner_iteration_cost;
-
+  if (is_not_silent_) {
+    VLOG(2) << "Inner iteration succeeded; Current cost: " << x_cost_
+            << " Trust region step cost: " << candidate_cost_
+            << " Inner iteration cost: " << inner_iteration_cost;
+  }
   candidate_x_ = inner_iteration_x_;
 
   // Normally, the quality of a trust region step is measured by
@@ -535,9 +556,10 @@
   // drops below tolerance.
   inner_iterations_are_enabled_ =
       (inner_iteration_relative_progress > options_.inner_iteration_tolerance);
-  VLOG_IF(2, is_not_silent_ && !inner_iterations_are_enabled_)
-      << "Disabling inner iterations. Progress : "
-      << inner_iteration_relative_progress;
+  if (is_not_silent_ && !inner_iterations_are_enabled_) {
+    VLOG(2) << "Disabling inner iterations. Progress : "
+            << inner_iteration_relative_progress;
+  }
   candidate_cost_ = inner_iteration_cost;
 
   solver_summary_->inner_iteration_time_in_seconds +=
@@ -609,12 +631,15 @@
     return false;
   }
 
-  solver_summary_->message = StringPrintf("Maximum solver time reached. "
-                                          "Total solver time: %e >= %e.",
-                                          total_solver_time,
-                                          options_.max_solver_time_in_seconds);
+  solver_summary_->message = StringPrintf(
+      "Maximum solver time reached. "
+      "Total solver time: %e >= %e.",
+      total_solver_time,
+      options_.max_solver_time_in_seconds);
   solver_summary_->termination_type = NO_CONVERGENCE;
-  VLOG_IF(1, is_not_silent_) << "Terminating: " << solver_summary_->message;
+  if (is_not_silent_) {
+    VLOG(1) << "Terminating: " << solver_summary_->message;
+  }
   return true;
 }
 
@@ -626,13 +651,15 @@
     return false;
   }
 
-  solver_summary_->message =
-      StringPrintf("Maximum number of iterations reached. "
-                   "Number of iterations: %d.",
-                   iteration_summary_.iteration);
+  solver_summary_->message = StringPrintf(
+      "Maximum number of iterations reached. "
+      "Number of iterations: %d.",
+      iteration_summary_.iteration);
 
   solver_summary_->termination_type = NO_CONVERGENCE;
-  VLOG_IF(1, is_not_silent_) << "Terminating: " << solver_summary_->message;
+  if (is_not_silent_) {
+    VLOG(1) << "Terminating: " << solver_summary_->message;
+  }
   return true;
 }
 
@@ -650,7 +677,9 @@
       iteration_summary_.gradient_max_norm,
       options_.gradient_tolerance);
   solver_summary_->termination_type = CONVERGENCE;
-  VLOG_IF(1, is_not_silent_) << "Terminating: " << solver_summary_->message;
+  if (is_not_silent_) {
+    VLOG(1) << "Terminating: " << solver_summary_->message;
+  }
   return true;
 }
 
@@ -661,13 +690,15 @@
     return false;
   }
 
-  solver_summary_->message =
-      StringPrintf("Minimum trust region radius reached. "
-                   "Trust region radius: %e <= %e",
-                   iteration_summary_.trust_region_radius,
-                   options_.min_trust_region_radius);
+  solver_summary_->message = StringPrintf(
+      "Minimum trust region radius reached. "
+      "Trust region radius: %e <= %e",
+      iteration_summary_.trust_region_radius,
+      options_.min_trust_region_radius);
   solver_summary_->termination_type = CONVERGENCE;
-  VLOG_IF(1, is_not_silent_) << "Terminating: " << solver_summary_->message;
+  if (is_not_silent_) {
+    VLOG(1) << "Terminating: " << solver_summary_->message;
+  }
   return true;
 }
 
@@ -688,7 +719,9 @@
       (iteration_summary_.step_norm / (x_norm_ + options_.parameter_tolerance)),
       options_.parameter_tolerance);
   solver_summary_->termination_type = CONVERGENCE;
-  VLOG_IF(1, is_not_silent_) << "Terminating: " << solver_summary_->message;
+  if (is_not_silent_) {
+    VLOG(1) << "Terminating: " << solver_summary_->message;
+  }
   return true;
 }
 
@@ -708,7 +741,9 @@
       fabs(iteration_summary_.cost_change) / x_cost_,
       options_.function_tolerance);
   solver_summary_->termination_type = CONVERGENCE;
-  VLOG_IF(1, is_not_silent_) << "Terminating: " << solver_summary_->message;
+  if (is_not_silent_) {
+    VLOG(1) << "Terminating: " << solver_summary_->message;
+  }
   return true;
 }
 
@@ -725,18 +760,20 @@
 // CostFunction objects.
 void TrustRegionMinimizer::ComputeCandidatePointAndEvaluateCost() {
   if (!evaluator_->Plus(x_.data(), delta_.data(), candidate_x_.data())) {
-    LOG_IF(WARNING, is_not_silent_)
-        << "x_plus_delta = Plus(x, delta) failed. "
-        << "Treating it as a step with infinite cost";
+    if (is_not_silent_) {
+      LOG(WARNING) << "x_plus_delta = Plus(x, delta) failed. "
+                   << "Treating it as a step with infinite cost";
+    }
     candidate_cost_ = std::numeric_limits<double>::max();
     return;
   }
 
   if (!evaluator_->Evaluate(
-          candidate_x_.data(), &candidate_cost_, NULL, NULL, NULL)) {
-    LOG_IF(WARNING, is_not_silent_)
-        << "Step failed to evaluate. "
-        << "Treating it as a step with infinite cost";
+          candidate_x_.data(), &candidate_cost_, nullptr, nullptr, nullptr)) {
+    if (is_not_silent_) {
+      LOG(WARNING) << "Step failed to evaluate. "
+                   << "Treating it as a step with infinite cost";
+    }
     candidate_cost_ = std::numeric_limits<double>::max();
   }
 }
@@ -788,12 +825,5 @@
   return true;
 }
 
-// Declare the step unsuccessful and inform the trust region strategy.
-void TrustRegionMinimizer::HandleUnsuccessfulStep() {
-  iteration_summary_.step_is_successful = false;
-  strategy_->StepRejected(iteration_summary_.relative_decrease);
-  iteration_summary_.cost = candidate_cost_ + solver_summary_->fixed_cost;
-}
-
 }  // namespace internal
 }  // namespace ceres
diff --git a/internal/ceres/trust_region_minimizer.h b/internal/ceres/trust_region_minimizer.h
index 8ddd77e..be4d406 100644
--- a/internal/ceres/trust_region_minimizer.h
+++ b/internal/ceres/trust_region_minimizer.h
@@ -32,7 +32,9 @@
 #define CERES_INTERNAL_TRUST_REGION_MINIMIZER_H_
 
 #include <memory>
+
 #include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
 #include "ceres/minimizer.h"
 #include "ceres/solver.h"
 #include "ceres/sparse_matrix.h"
@@ -46,14 +48,14 @@
 // Generic trust region minimization algorithm.
 //
 // For example usage, see SolverImpl::Minimize.
-class TrustRegionMinimizer : public Minimizer {
+class CERES_EXPORT_INTERNAL TrustRegionMinimizer : public Minimizer {
  public:
   ~TrustRegionMinimizer();
 
   // This method is not thread safe.
-  virtual void Minimize(const Minimizer::Options& options,
-                        double* parameters,
-                        Solver::Summary* solver_summary);
+  void Minimize(const Minimizer::Options& options,
+                double* parameters,
+                Solver::Summary* solver_summary) override;
 
  private:
   void Init(const Minimizer::Options& options,
@@ -80,7 +82,6 @@
   bool MinTrustRegionRadiusReached();
 
   bool IsStepSuccessful();
-  void HandleUnsuccessfulStep();
   bool HandleSuccessfulStep();
   bool HandleInvalidStep();
 
diff --git a/internal/ceres/trust_region_minimizer_test.cc b/internal/ceres/trust_region_minimizer_test.cc
index 0c4ea29..8993273 100644
--- a/internal/ceres/trust_region_minimizer_test.cc
+++ b/internal/ceres/trust_region_minimizer_test.cc
@@ -33,7 +33,10 @@
 // implementation, rather than having a test that goes through all the
 // Program and Problem machinery.
 
+#include "ceres/trust_region_minimizer.h"
+
 #include <cmath>
+
 #include "ceres/autodiff_cost_function.h"
 #include "ceres/cost_function.h"
 #include "ceres/dense_qr_solver.h"
@@ -43,7 +46,6 @@
 #include "ceres/linear_solver.h"
 #include "ceres/minimizer.h"
 #include "ceres/problem.h"
-#include "ceres/trust_region_minimizer.h"
 #include "ceres/trust_region_strategy.h"
 #include "gtest/gtest.h"
 
@@ -59,6 +61,7 @@
 template <bool col1, bool col2, bool col3, bool col4>
 class PowellEvaluator2 : public Evaluator {
  public:
+  // clang-format off
   PowellEvaluator2()
       : num_active_cols_(
           (col1 ? 1 : 0) +
@@ -71,11 +74,12 @@
             << col3 << " "
             << col4;
   }
+  // clang-format on
 
   virtual ~PowellEvaluator2() {}
 
   // Implementation of Evaluator interface.
-  virtual SparseMatrix* CreateJacobian() const {
+  SparseMatrix* CreateJacobian() const final {
     CHECK(col1 || col2 || col3 || col4);
     DenseSparseMatrix* dense_jacobian =
         new DenseSparseMatrix(NumResiduals(), NumEffectiveParameters());
@@ -83,12 +87,12 @@
     return dense_jacobian;
   }
 
-  virtual bool Evaluate(const Evaluator::EvaluateOptions& evaluate_options,
-                        const double* state,
-                        double* cost,
-                        double* residuals,
-                        double* gradient,
-                        SparseMatrix* jacobian) {
+  bool Evaluate(const Evaluator::EvaluateOptions& evaluate_options,
+                const double* state,
+                double* cost,
+                double* residuals,
+                double* gradient,
+                SparseMatrix* jacobian) final {
     const double x1 = state[0];
     const double x2 = state[1];
     const double x3 = state[2];
@@ -111,7 +115,7 @@
             << "f3=" << f3 << ", "
             << "f4=" << f4 << ".";
 
-    *cost = (f1*f1 + f2*f2 + f3*f3 + f4*f4) / 2.0;
+    *cost = (f1 * f1 + f2 * f2 + f3 * f3 + f4 * f4) / 2.0;
 
     VLOG(1) << "Cost: " << *cost;
 
@@ -132,34 +136,42 @@
 
       int column_index = 0;
       if (col1) {
+        // clang-format off
         jacobian_matrix.col(column_index++) <<
             1.0,
             0.0,
             0.0,
             sqrt(10.0) * 2.0 * (x1 - x4) * (1.0 - x4);
+        // clang-format on
       }
       if (col2) {
+        // clang-format off
         jacobian_matrix.col(column_index++) <<
             10.0,
             0.0,
             2.0*(x2 - 2.0*x3)*(1.0 - 2.0*x3),
             0.0;
+        // clang-format on
       }
 
       if (col3) {
+        // clang-format off
         jacobian_matrix.col(column_index++) <<
             0.0,
             sqrt(5.0),
             2.0*(x2 - 2.0*x3)*(x2 - 2.0),
             0.0;
+        // clang-format on
       }
 
       if (col4) {
+        // clang-format off
         jacobian_matrix.col(column_index++) <<
             0.0,
             -sqrt(5.0),
             0.0,
             sqrt(10.0) * 2.0 * (x1 - x4) * (x1 - 1.0);
+        // clang-format on
       }
       VLOG(1) << "\n" << jacobian_matrix;
     }
@@ -167,7 +179,7 @@
     if (gradient != NULL) {
       int column_index = 0;
       if (col1) {
-        gradient[column_index++] = f1  + f4 * sqrt(10.0) * 2.0 * (x1 - x4);
+        gradient[column_index++] = f1 + f4 * sqrt(10.0) * 2.0 * (x1 - x4);
       }
 
       if (col2) {
@@ -188,20 +200,20 @@
     return true;
   }
 
-  virtual bool Plus(const double* state,
-                    const double* delta,
-                    double* state_plus_delta) const {
+  bool Plus(const double* state,
+            const double* delta,
+            double* state_plus_delta) const final {
     int delta_index = 0;
-    state_plus_delta[0] = (col1  ? state[0] + delta[delta_index++] : state[0]);
-    state_plus_delta[1] = (col2  ? state[1] + delta[delta_index++] : state[1]);
-    state_plus_delta[2] = (col3  ? state[2] + delta[delta_index++] : state[2]);
-    state_plus_delta[3] = (col4  ? state[3] + delta[delta_index++] : state[3]);
+    state_plus_delta[0] = (col1 ? state[0] + delta[delta_index++] : state[0]);
+    state_plus_delta[1] = (col2 ? state[1] + delta[delta_index++] : state[1]);
+    state_plus_delta[2] = (col3 ? state[2] + delta[delta_index++] : state[2]);
+    state_plus_delta[3] = (col4 ? state[3] + delta[delta_index++] : state[3]);
     return true;
   }
 
-  virtual int NumEffectiveParameters() const { return num_active_cols_; }
-  virtual int NumParameters()          const { return 4; }
-  virtual int NumResiduals()           const { return 4; }
+  int NumEffectiveParameters() const final { return num_active_cols_; }
+  int NumParameters() const final { return 4; }
+  int NumResiduals() const final { return 4; }
 
  private:
   const int num_active_cols_;
@@ -209,13 +221,13 @@
 
 // Templated function to hold a subset of the columns fixed and check
 // if the solver converges to the optimal values or not.
-template<bool col1, bool col2, bool col3, bool col4>
+template <bool col1, bool col2, bool col3, bool col4>
 void IsTrustRegionSolveSuccessful(TrustRegionStrategyType strategy_type) {
   Solver::Options solver_options;
   LinearSolver::Options linear_solver_options;
   DenseQRSolver linear_solver(linear_solver_options);
 
-  double parameters[4] = { 3, -1, 0, 1.0 };
+  double parameters[4] = {3, -1, 0, 1.0};
 
   // If the column is inactive, then set its value to the optimal
   // value.
@@ -263,6 +275,7 @@
   //   IsSolveSuccessful<true, true, false, true>();
 
   const TrustRegionStrategyType kStrategy = LEVENBERG_MARQUARDT;
+  // clang-format off
   IsTrustRegionSolveSuccessful<true,  true,  true,  true >(kStrategy);
   IsTrustRegionSolveSuccessful<true,  true,  true,  false>(kStrategy);
   IsTrustRegionSolveSuccessful<true,  false, true,  true >(kStrategy);
@@ -277,6 +290,7 @@
   IsTrustRegionSolveSuccessful<false, true,  false, false>(kStrategy);
   IsTrustRegionSolveSuccessful<false, false, true,  false>(kStrategy);
   IsTrustRegionSolveSuccessful<false, false, false, true >(kStrategy);
+  // clang-format on
 }
 
 TEST(TrustRegionMinimizer, PowellsSingularFunctionUsingDogleg) {
@@ -287,6 +301,7 @@
   //  IsTrustRegionSolveSuccessful<true,  true,  true,  true >(kStrategy);
 
   const TrustRegionStrategyType kStrategy = DOGLEG;
+  // clang-format off
   IsTrustRegionSolveSuccessful<true,  true,  true,  false>(kStrategy);
   IsTrustRegionSolveSuccessful<true,  false, true,  true >(kStrategy);
   IsTrustRegionSolveSuccessful<false, true,  true,  true >(kStrategy);
@@ -300,9 +315,9 @@
   IsTrustRegionSolveSuccessful<false, true,  false, false>(kStrategy);
   IsTrustRegionSolveSuccessful<false, false, true,  false>(kStrategy);
   IsTrustRegionSolveSuccessful<false, false, false, true >(kStrategy);
+  // clang-format on
 }
 
-
 class CurveCostFunction : public CostFunction {
  public:
   CurveCostFunction(int num_vertices, double target_length)
@@ -352,11 +367,11 @@
         for (int dim = 0; dim < 2; dim++) {
           jacobians[i][dim] = 0.;
 
-          if (norm_u > std::numeric_limits< double >::min()) {
+          if (norm_u > std::numeric_limits<double>::min()) {
             jacobians[i][dim] -= u[dim] / norm_u;
           }
 
-          if (norm_v > std::numeric_limits< double >::min()) {
+          if (norm_v > std::numeric_limits<double>::min()) {
             jacobians[i][dim] += v[dim] / norm_v;
           }
         }
@@ -367,8 +382,8 @@
   }
 
  private:
-  int     num_vertices_;
-  double  target_length_;
+  int num_vertices_;
+  double target_length_;
 };
 
 TEST(TrustRegionMinimizer, JacobiScalingTest) {
@@ -376,7 +391,7 @@
   std::vector<double*> y(N);
   const double pi = 3.1415926535897932384626433;
   for (int i = 0; i < N; i++) {
-    double theta = i * 2. * pi/ static_cast< double >(N);
+    double theta = i * 2. * pi / static_cast<double>(N);
     y[i] = new double[2];
     y[i][0] = cos(theta);
     y[i][1] = sin(theta);
@@ -391,7 +406,7 @@
   EXPECT_LE(summary.final_cost, 1e-10);
 
   for (int i = 0; i < N; i++) {
-    delete []y[i];
+    delete[] y[i];
   }
 }
 
@@ -403,8 +418,7 @@
   }
 
   static CostFunction* Create() {
-    return new AutoDiffCostFunction<ExpCostFunctor, 1, 1>(
-        new ExpCostFunctor);
+    return new AutoDiffCostFunction<ExpCostFunctor, 1, 1>(new ExpCostFunctor);
   }
 };
 
diff --git a/internal/ceres/trust_region_preprocessor.cc b/internal/ceres/trust_region_preprocessor.cc
index aa7f095..0943edb 100644
--- a/internal/ceres/trust_region_preprocessor.cc
+++ b/internal/ceres/trust_region_preprocessor.cc
@@ -32,6 +32,7 @@
 
 #include <numeric>
 #include <string>
+
 #include "ceres/callbacks.h"
 #include "ceres/context_impl.h"
 #include "ceres/evaluator.h"
@@ -57,8 +58,7 @@
 ParameterBlockOrdering* CreateDefaultLinearSolverOrdering(
     const Program& program) {
   ParameterBlockOrdering* ordering = new ParameterBlockOrdering;
-  const vector<ParameterBlock*>& parameter_blocks =
-      program.parameter_blocks();
+  const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
   for (int i = 0; i < parameter_blocks.size(); ++i) {
     ordering->AddElementToGroup(
         const_cast<double*>(parameter_blocks[i]->user_state()), 0);
@@ -69,8 +69,7 @@
 // Check if all the user supplied values in the parameter blocks are
 // sane or not, and if the program is feasible or not.
 bool IsProgramValid(const Program& program, std::string* error) {
-  return (program.ParameterBlocksAreFinite(error) &&
-          program.IsFeasible(error));
+  return (program.ParameterBlocksAreFinite(error) && program.IsFeasible(error));
 }
 
 void AlternateLinearSolverAndPreconditionerForSchurTypeLinearSolver(
@@ -82,34 +81,32 @@
   const LinearSolverType linear_solver_type_given = options->linear_solver_type;
   const PreconditionerType preconditioner_type_given =
       options->preconditioner_type;
-  options->linear_solver_type = LinearSolver::LinearSolverForZeroEBlocks(
-      linear_solver_type_given);
+  options->linear_solver_type =
+      LinearSolver::LinearSolverForZeroEBlocks(linear_solver_type_given);
 
   std::string message;
   if (linear_solver_type_given == ITERATIVE_SCHUR) {
-    options->preconditioner_type = Preconditioner::PreconditionerForZeroEBlocks(
-        preconditioner_type_given);
+    options->preconditioner_type =
+        Preconditioner::PreconditionerForZeroEBlocks(preconditioner_type_given);
 
     message =
-        StringPrintf(
-            "No E blocks. Switching from %s(%s) to %s(%s).",
-            LinearSolverTypeToString(linear_solver_type_given),
-            PreconditionerTypeToString(preconditioner_type_given),
-            LinearSolverTypeToString(options->linear_solver_type),
-            PreconditionerTypeToString(options->preconditioner_type));
+        StringPrintf("No E blocks. Switching from %s(%s) to %s(%s).",
+                     LinearSolverTypeToString(linear_solver_type_given),
+                     PreconditionerTypeToString(preconditioner_type_given),
+                     LinearSolverTypeToString(options->linear_solver_type),
+                     PreconditionerTypeToString(options->preconditioner_type));
   } else {
     message =
-        StringPrintf(
-            "No E blocks. Switching from %s to %s.",
-            LinearSolverTypeToString(linear_solver_type_given),
-            LinearSolverTypeToString(options->linear_solver_type));
+        StringPrintf("No E blocks. Switching from %s to %s.",
+                     LinearSolverTypeToString(linear_solver_type_given),
+                     LinearSolverTypeToString(options->linear_solver_type));
   }
-
-  VLOG_IF(1, options->logging_type != SILENT) << message;
+  if (options->logging_type != SILENT) {
+    VLOG(1) << message;
+  }
 }
 
-// For Schur type and SPARSE_NORMAL_CHOLESKY linear solvers, reorder
-// the program to reduce fill-in and increase cache coherency.
+// Reorder the program to reduce fill-in and increase cache coherency.
 bool ReorderProgram(PreprocessedProblem* pp) {
   const Solver::Options& options = pp->options;
   if (IsSchurType(options.linear_solver_type)) {
@@ -122,12 +119,27 @@
         &pp->error);
   }
 
-
   if (options.linear_solver_type == SPARSE_NORMAL_CHOLESKY &&
       !options.dynamic_sparsity) {
-    return ReorderProgramForSparseNormalCholesky(
+    return ReorderProgramForSparseCholesky(
         options.sparse_linear_algebra_library_type,
         *options.linear_solver_ordering,
+        0, /* use all the rows of the jacobian */
+        pp->reduced_program.get(),
+        &pp->error);
+  }
+
+  if (options.linear_solver_type == CGNR &&
+      options.preconditioner_type == SUBSET) {
+    pp->linear_solver_options.subset_preconditioner_start_row_block =
+        ReorderResidualBlocksByPartition(
+            options.residual_blocks_for_subset_preconditioner,
+            pp->reduced_program.get());
+
+    return ReorderProgramForSparseCholesky(
+        options.sparse_linear_algebra_library_type,
+        *options.linear_solver_ordering,
+        pp->linear_solver_options.subset_preconditioner_start_row_block,
         pp->reduced_program.get(),
         &pp->error);
   }
@@ -141,7 +153,9 @@
 // too.
 bool SetupLinearSolver(PreprocessedProblem* pp) {
   Solver::Options& options = pp->options;
-  if (options.linear_solver_ordering.get() == NULL) {
+  pp->linear_solver_options = LinearSolver::Options();
+
+  if (!options.linear_solver_ordering) {
     // If the user has not supplied a linear solver ordering, then we
     // assume that they are giving all the freedom to us in choosing
     // the best possible ordering. This intent can be indicated by
@@ -165,8 +179,7 @@
     ordering->Remove(pp->removed_parameter_blocks);
     if (IsSchurType(options.linear_solver_type) &&
         min_group_id != ordering->MinNonZeroGroup()) {
-      AlternateLinearSolverAndPreconditionerForSchurTypeLinearSolver(
-          &options);
+      AlternateLinearSolverAndPreconditionerForSchurTypeLinearSolver(&options);
     }
   }
 
@@ -177,7 +190,6 @@
   }
 
   // Configure the linear solver.
-  pp->linear_solver_options = LinearSolver::Options();
   pp->linear_solver_options.min_num_iterations =
       options.min_linear_solver_iterations;
   pp->linear_solver_options.max_num_iterations =
@@ -228,7 +240,7 @@
       // blocks for CX_SPARSE.
       if ((options.sparse_linear_algebra_library_type == SUITE_SPARSE &&
            !SuiteSparse::
-           IsConstrainedApproximateMinimumDegreeOrderingAvailable()) ||
+               IsConstrainedApproximateMinimumDegreeOrderingAvailable()) ||
           (options.sparse_linear_algebra_library_type == CX_SPARSE)) {
         pp->linear_solver_options.use_postordering = true;
       }
@@ -236,7 +248,7 @@
   }
 
   pp->linear_solver.reset(LinearSolver::Create(pp->linear_solver_options));
-  return (pp->linear_solver.get() != NULL);
+  return (pp->linear_solver != nullptr);
 }
 
 // Configure and create the evaluator.
@@ -247,21 +259,20 @@
   pp->evaluator_options.num_eliminate_blocks = 0;
   if (IsSchurType(options.linear_solver_type)) {
     pp->evaluator_options.num_eliminate_blocks =
-        options
-        .linear_solver_ordering
-        ->group_to_elements().begin()
-        ->second.size();
+        options.linear_solver_ordering->group_to_elements()
+            .begin()
+            ->second.size();
   }
 
   pp->evaluator_options.num_threads = options.num_threads;
   pp->evaluator_options.dynamic_sparsity = options.dynamic_sparsity;
   pp->evaluator_options.context = pp->problem->context();
-  pp->evaluator_options.evaluation_callback = options.evaluation_callback;
-  pp->evaluator.reset(Evaluator::Create(pp->evaluator_options,
-                                        pp->reduced_program.get(),
-                                        &pp->error));
+  pp->evaluator_options.evaluation_callback =
+      pp->reduced_program->mutable_evaluation_callback();
+  pp->evaluator.reset(Evaluator::Create(
+      pp->evaluator_options, pp->reduced_program.get(), &pp->error));
 
-  return (pp->evaluator.get() != NULL);
+  return (pp->evaluator != nullptr);
 }
 
 // If the user requested inner iterations, then find an inner
@@ -273,6 +284,11 @@
     return true;
   }
 
+  if (pp->reduced_program->mutable_evaluation_callback()) {
+    pp->error = "Inner iterations cannot be used with EvaluationCallbacks";
+    return false;
+  }
+
   // With just one parameter block, the outer iteration of the trust
   // region method and inner iterations are doing exactly the same
   // thing, and thus inner iterations are not needed.
@@ -282,7 +298,7 @@
     return true;
   }
 
-  if (options.inner_iteration_ordering.get() != NULL) {
+  if (options.inner_iteration_ordering != nullptr) {
     // If the user supplied an ordering, then remove the set of
     // inactive parameter blocks from it
     options.inner_iteration_ordering->Remove(pp->removed_parameter_blocks);
@@ -325,8 +341,7 @@
 
   TrustRegionStrategy::Options strategy_options;
   strategy_options.linear_solver = pp->linear_solver.get();
-  strategy_options.initial_radius =
-      options.initial_trust_region_radius;
+  strategy_options.initial_radius = options.initial_trust_region_radius;
   strategy_options.max_radius = options.max_trust_region_radius;
   strategy_options.min_lm_diagonal = options.min_lm_diagonal;
   strategy_options.max_lm_diagonal = options.max_lm_diagonal;
@@ -340,8 +355,7 @@
 
 }  // namespace
 
-TrustRegionPreprocessor::~TrustRegionPreprocessor() {
-}
+TrustRegionPreprocessor::~TrustRegionPreprocessor() {}
 
 bool TrustRegionPreprocessor::Preprocess(const Solver::Options& options,
                                          ProblemImpl* problem,
@@ -356,10 +370,8 @@
     return false;
   }
 
-  pp->reduced_program.reset(
-      program->CreateReducedProgram(&pp->removed_parameter_blocks,
-                                    &pp->fixed_cost,
-                                    &pp->error));
+  pp->reduced_program.reset(program->CreateReducedProgram(
+      &pp->removed_parameter_blocks, &pp->fixed_cost, &pp->error));
 
   if (pp->reduced_program.get() == NULL) {
     return false;
@@ -371,8 +383,7 @@
     return true;
   }
 
-  if (!SetupLinearSolver(pp) ||
-      !SetupEvaluator(pp) ||
+  if (!SetupLinearSolver(pp) || !SetupEvaluator(pp) ||
       !SetupInnerIterationMinimizer(pp)) {
     return false;
   }
diff --git a/internal/ceres/trust_region_preprocessor.h b/internal/ceres/trust_region_preprocessor.h
index a6631ab..2655abe 100644
--- a/internal/ceres/trust_region_preprocessor.h
+++ b/internal/ceres/trust_region_preprocessor.h
@@ -31,17 +31,18 @@
 #ifndef CERES_INTERNAL_TRUST_REGION_PREPROCESSOR_H_
 #define CERES_INTERNAL_TRUST_REGION_PREPROCESSOR_H_
 
+#include "ceres/internal/port.h"
 #include "ceres/preprocessor.h"
 
 namespace ceres {
 namespace internal {
 
-class TrustRegionPreprocessor : public Preprocessor {
+class CERES_EXPORT_INTERNAL TrustRegionPreprocessor : public Preprocessor {
  public:
   virtual ~TrustRegionPreprocessor();
-  virtual bool Preprocess(const Solver::Options& options,
-                          ProblemImpl* problem,
-                          PreprocessedProblem* preprocessed_problem);
+  bool Preprocess(const Solver::Options& options,
+                  ProblemImpl* problem,
+                  PreprocessedProblem* preprocessed_problem) override;
 };
 
 }  // namespace internal
diff --git a/internal/ceres/trust_region_preprocessor_test.cc b/internal/ceres/trust_region_preprocessor_test.cc
index 40338c1..a2a9523 100644
--- a/internal/ceres/trust_region_preprocessor_test.cc
+++ b/internal/ceres/trust_region_preprocessor_test.cc
@@ -28,6 +28,8 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/trust_region_preprocessor.h"
+
 #include <array>
 #include <map>
 
@@ -35,7 +37,6 @@
 #include "ceres/problem_impl.h"
 #include "ceres/sized_cost_function.h"
 #include "ceres/solver.h"
-#include "ceres/trust_region_preprocessor.h"
 #include "gtest/gtest.h"
 
 namespace ceres {
@@ -143,12 +144,14 @@
 
 class LinearSolverAndEvaluatorCreationTest : public ::testing::Test {
  public:
-  virtual void SetUp() {
+  void SetUp() final {
     x_ = 1.0;
     y_ = 1.0;
     z_ = 1.0;
-    problem_.AddResidualBlock(new DummyCostFunction<1, 1, 1>, nullptr, &x_, &y_);
-    problem_.AddResidualBlock(new DummyCostFunction<1, 1, 1>, nullptr, &y_, &z_);
+    problem_.AddResidualBlock(
+        new DummyCostFunction<1, 1, 1>, nullptr, &x_, &y_);
+    problem_.AddResidualBlock(
+        new DummyCostFunction<1, 1, 1>, nullptr, &y_, &z_);
   }
 
   void PreprocessForGivenLinearSolverAndVerify(
@@ -322,8 +325,7 @@
   EXPECT_TRUE(pp.inner_iteration_minimizer.get() != nullptr);
 }
 
-TEST_F(LinearSolverAndEvaluatorCreationTest,
-       InvalidInnerIterationsOrdering) {
+TEST_F(LinearSolverAndEvaluatorCreationTest, InvalidInnerIterationsOrdering) {
   Solver::Options options;
   options.use_inner_iterations = true;
   options.inner_iteration_ordering.reset(new ParameterBlockOrdering);
diff --git a/internal/ceres/trust_region_step_evaluator.cc b/internal/ceres/trust_region_step_evaluator.cc
index 33b0c41..19045ae 100644
--- a/internal/ceres/trust_region_step_evaluator.cc
+++ b/internal/ceres/trust_region_step_evaluator.cc
@@ -28,17 +28,18 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/trust_region_step_evaluator.h"
+
 #include <algorithm>
 #include <limits>
-#include "ceres/trust_region_step_evaluator.h"
+
 #include "glog/logging.h"
 
 namespace ceres {
 namespace internal {
 
 TrustRegionStepEvaluator::TrustRegionStepEvaluator(
-    const double initial_cost,
-    const int max_consecutive_nonmonotonic_steps)
+    const double initial_cost, const int max_consecutive_nonmonotonic_steps)
     : max_consecutive_nonmonotonic_steps_(max_consecutive_nonmonotonic_steps),
       minimum_cost_(initial_cost),
       current_cost_(initial_cost),
@@ -46,12 +47,10 @@
       candidate_cost_(initial_cost),
       accumulated_reference_model_cost_change_(0.0),
       accumulated_candidate_model_cost_change_(0.0),
-      num_consecutive_nonmonotonic_steps_(0){
-}
+      num_consecutive_nonmonotonic_steps_(0) {}
 
 double TrustRegionStepEvaluator::StepQuality(
-    const double cost,
-    const double model_cost_change) const {
+    const double cost, const double model_cost_change) const {
   // If the function evaluation for this step was a failure, in which
   // case the TrustRegionMinimizer would have set the cost to
   // std::numeric_limits<double>::max(). In this case, the division by
@@ -68,9 +67,8 @@
   return std::max(relative_decrease, historical_relative_decrease);
 }
 
-void TrustRegionStepEvaluator::StepAccepted(
-    const double cost,
-    const double model_cost_change) {
+void TrustRegionStepEvaluator::StepAccepted(const double cost,
+                                            const double model_cost_change) {
   // Algorithm 10.1.2 from Trust Region Methods by Conn, Gould &
   // Toint.
   //
diff --git a/internal/ceres/trust_region_strategy.cc b/internal/ceres/trust_region_strategy.cc
index 2db6a6c..7e429d5 100644
--- a/internal/ceres/trust_region_strategy.cc
+++ b/internal/ceres/trust_region_strategy.cc
@@ -31,6 +31,7 @@
 //         keir@google.com (Keir Mierle)
 
 #include "ceres/trust_region_strategy.h"
+
 #include "ceres/dogleg_strategy.h"
 #include "ceres/levenberg_marquardt_strategy.h"
 
diff --git a/internal/ceres/trust_region_strategy.h b/internal/ceres/trust_region_strategy.h
index b3b2e5d..176f73a 100644
--- a/internal/ceres/trust_region_strategy.h
+++ b/internal/ceres/trust_region_strategy.h
@@ -32,6 +32,7 @@
 #define CERES_INTERNAL_TRUST_REGION_STRATEGY_H_
 
 #include <string>
+
 #include "ceres/internal/port.h"
 #include "ceres/linear_solver.h"
 
@@ -53,7 +54,7 @@
 // the LevenbergMarquardtStrategy uses the inverse of the trust region
 // radius to scale the damping term, which controls the step size, but
 // does not set a hard limit on its size.
-class TrustRegionStrategy {
+class CERES_EXPORT_INTERNAL TrustRegionStrategy {
  public:
   struct Options {
     TrustRegionStrategyType trust_region_strategy_type = LEVENBERG_MARQUARDT;
@@ -73,6 +74,11 @@
     DoglegType dogleg_type = TRADITIONAL_DOGLEG;
   };
 
+  // Factory.
+  static TrustRegionStrategy* Create(const Options& options);
+
+  virtual ~TrustRegionStrategy();
+
   // Per solve options.
   struct PerSolveOptions {
     // Forcing sequence for inexact solves.
@@ -107,8 +113,6 @@
     LinearSolverTerminationType termination_type = LINEAR_SOLVER_FAILURE;
   };
 
-  virtual ~TrustRegionStrategy();
-
   // Use the current radius to solve for the trust region step.
   virtual Summary ComputeStep(const PerSolveOptions& per_solve_options,
                               SparseMatrix* jacobian,
@@ -133,9 +137,6 @@
 
   // Current trust region radius.
   virtual double Radius() const = 0;
-
-  // Factory.
-  static TrustRegionStrategy* Create(const Options& options);
 };
 
 }  // namespace internal
diff --git a/internal/ceres/types.cc b/internal/ceres/types.cc
index 932ec7d..39bb2d8 100644
--- a/internal/ceres/types.cc
+++ b/internal/ceres/types.cc
@@ -28,18 +28,22 @@
 //
 // Author: sameeragarwal@google.com (Sameer Agarwal)
 
+#include "ceres/types.h"
+
 #include <algorithm>
 #include <cctype>
 #include <string>
-#include "ceres/types.h"
+
 #include "glog/logging.h"
 
 namespace ceres {
 
 using std::string;
 
+// clang-format off
 #define CASESTR(x) case x: return #x
-#define STRENUM(x) if (value == #x) { *type = x; return true;}
+#define STRENUM(x) if (value == #x) { *type = x; return true; }
+// clang-format on
 
 static void UpperCase(string* input) {
   std::transform(input->begin(), input->end(), input->begin(), ::toupper);
@@ -78,6 +82,7 @@
     CASESTR(SCHUR_JACOBI);
     CASESTR(CLUSTER_JACOBI);
     CASESTR(CLUSTER_TRIDIAGONAL);
+    CASESTR(SUBSET);
     default:
       return "UNKNOWN";
   }
@@ -90,6 +95,7 @@
   STRENUM(SCHUR_JACOBI);
   STRENUM(CLUSTER_JACOBI);
   STRENUM(CLUSTER_TRIDIAGONAL);
+  STRENUM(SUBSET);
   return false;
 }
 
@@ -107,8 +113,7 @@
 }
 
 bool StringToSparseLinearAlgebraLibraryType(
-    string value,
-    SparseLinearAlgebraLibraryType* type) {
+    string value, SparseLinearAlgebraLibraryType* type) {
   UpperCase(&value);
   STRENUM(SUITE_SPARSE);
   STRENUM(CX_SPARSE);
@@ -129,8 +134,7 @@
 }
 
 bool StringToDenseLinearAlgebraLibraryType(
-    string value,
-    DenseLinearAlgebraLibraryType* type) {
+    string value, DenseLinearAlgebraLibraryType* type) {
   UpperCase(&value);
   STRENUM(EIGEN);
   STRENUM(LAPACK);
@@ -234,9 +238,8 @@
   }
 }
 
-bool StringToLineSearchInterpolationType(
-    string value,
-    LineSearchInterpolationType* type) {
+bool StringToLineSearchInterpolationType(string value,
+                                         LineSearchInterpolationType* type) {
   UpperCase(&value);
   STRENUM(BISECTION);
   STRENUM(QUADRATIC);
@@ -256,8 +259,7 @@
 }
 
 bool StringToNonlinearConjugateGradientType(
-    string value,
-    NonlinearConjugateGradientType* type) {
+    string value, NonlinearConjugateGradientType* type) {
   UpperCase(&value);
   STRENUM(FLETCHER_REEVES);
   STRENUM(POLAK_RIBIERE);
@@ -265,8 +267,7 @@
   return false;
 }
 
-const char* CovarianceAlgorithmTypeToString(
-    CovarianceAlgorithmType type) {
+const char* CovarianceAlgorithmTypeToString(CovarianceAlgorithmType type) {
   switch (type) {
     CASESTR(DENSE_SVD);
     CASESTR(SPARSE_QR);
@@ -275,17 +276,15 @@
   }
 }
 
-bool StringToCovarianceAlgorithmType(
-    string value,
-    CovarianceAlgorithmType* type) {
+bool StringToCovarianceAlgorithmType(string value,
+                                     CovarianceAlgorithmType* type) {
   UpperCase(&value);
   STRENUM(DENSE_SVD);
   STRENUM(SPARSE_QR);
   return false;
 }
 
-const char* NumericDiffMethodTypeToString(
-    NumericDiffMethodType type) {
+const char* NumericDiffMethodTypeToString(NumericDiffMethodType type) {
   switch (type) {
     CASESTR(CENTRAL);
     CASESTR(FORWARD);
@@ -295,9 +294,7 @@
   }
 }
 
-bool StringToNumericDiffMethodType(
-    string value,
-    NumericDiffMethodType* type) {
+bool StringToNumericDiffMethodType(string value, NumericDiffMethodType* type) {
   UpperCase(&value);
   STRENUM(CENTRAL);
   STRENUM(FORWARD);
@@ -305,8 +302,7 @@
   return false;
 }
 
-const char* VisibilityClusteringTypeToString(
-    VisibilityClusteringType type) {
+const char* VisibilityClusteringTypeToString(VisibilityClusteringType type) {
   switch (type) {
     CASESTR(CANONICAL_VIEWS);
     CASESTR(SINGLE_LINKAGE);
@@ -315,9 +311,8 @@
   }
 }
 
-bool StringToVisibilityClusteringType(
-    string value,
-    VisibilityClusteringType* type) {
+bool StringToVisibilityClusteringType(string value,
+                                      VisibilityClusteringType* type) {
   UpperCase(&value);
   STRENUM(CANONICAL_VIEWS);
   STRENUM(SINGLE_LINKAGE);
@@ -336,13 +331,47 @@
   }
 }
 
+const char* LoggingTypeToString(LoggingType type) {
+  switch (type) {
+    CASESTR(SILENT);
+    CASESTR(PER_MINIMIZER_ITERATION);
+    default:
+      return "UNKNOWN";
+  }
+}
+
+bool StringtoLoggingType(std::string value, LoggingType* type) {
+  UpperCase(&value);
+  STRENUM(SILENT);
+  STRENUM(PER_MINIMIZER_ITERATION);
+  return false;
+}
+
+const char* DumpFormatTypeToString(DumpFormatType type) {
+  switch (type) {
+    CASESTR(CONSOLE);
+    CASESTR(TEXTFILE);
+    default:
+      return "UNKNOWN";
+  }
+}
+
+bool StringtoDumpFormatType(std::string value, DumpFormatType* type) {
+  UpperCase(&value);
+  STRENUM(CONSOLE);
+  STRENUM(TEXTFILE);
+  return false;
+}
+
 #undef CASESTR
 #undef STRENUM
 
 bool IsSchurType(LinearSolverType type) {
+  // clang-format off
   return ((type == SPARSE_SCHUR) ||
           (type == DENSE_SCHUR)  ||
           (type == ITERATIVE_SCHUR));
+  // clang-format on
 }
 
 bool IsSparseLinearAlgebraLibraryTypeAvailable(
diff --git a/internal/ceres/visibility.cc b/internal/ceres/visibility.cc
index 72a1c33..82bf6f1 100644
--- a/internal/ceres/visibility.cc
+++ b/internal/ceres/visibility.cc
@@ -30,13 +30,14 @@
 
 #include "ceres/visibility.h"
 
+#include <algorithm>
 #include <cmath>
 #include <ctime>
-#include <algorithm>
 #include <set>
-#include <vector>
 #include <unordered_map>
 #include <utility>
+#include <vector>
+
 #include "ceres/block_structure.h"
 #include "ceres/graph.h"
 #include "ceres/pair_hash.h"
@@ -125,7 +126,7 @@
   // Add vertices and initialize the pairs for self edges so that self
   // edges are guaranteed. This is needed for the Canonical views
   // algorithm to work correctly.
-  static const double kSelfEdgeWeight = 1.0;
+  static constexpr double kSelfEdgeWeight = 1.0;
   for (int i = 0; i < visibility.size(); ++i) {
     graph->AddVertex(i);
     graph->AddEdge(i, i, kSelfEdgeWeight);
@@ -138,9 +139,10 @@
     const int count = camera_pair_count.second;
     DCHECK_NE(camera1, camera2);
     // Static cast necessary for Windows.
-    const double weight = static_cast<double>(count) /
-        (sqrt(static_cast<double>(
-                  visibility[camera1].size() * visibility[camera2].size())));
+    const double weight =
+        static_cast<double>(count) /
+        (sqrt(static_cast<double>(visibility[camera1].size() *
+                                  visibility[camera2].size())));
     graph->AddEdge(camera1, camera2, weight);
   }
 
diff --git a/internal/ceres/visibility.h b/internal/ceres/visibility.h
index 115d45f..68c6723 100644
--- a/internal/ceres/visibility.h
+++ b/internal/ceres/visibility.h
@@ -37,7 +37,9 @@
 
 #include <set>
 #include <vector>
+
 #include "ceres/graph.h"
+#include "ceres/internal/port.h"
 
 namespace ceres {
 namespace internal {
@@ -52,9 +54,10 @@
 //
 // In a structure from motion problem, e_blocks correspond to 3D
 // points and f_blocks correspond to cameras.
-void ComputeVisibility(const CompressedRowBlockStructure& block_structure,
-                       int num_eliminate_blocks,
-                       std::vector<std::set<int>>* visibility);
+CERES_EXPORT_INTERNAL void ComputeVisibility(
+    const CompressedRowBlockStructure& block_structure,
+    int num_eliminate_blocks,
+    std::vector<std::set<int>>* visibility);
 
 // Given f_block visibility as computed by the ComputeVisibility
 // function above, construct and return a graph whose vertices are
@@ -69,7 +72,7 @@
 //
 // Caller acquires ownership of the returned WeightedGraph pointer
 // (heap-allocated).
-WeightedGraph<int>* CreateSchurComplementGraph(
+CERES_EXPORT_INTERNAL WeightedGraph<int>* CreateSchurComplementGraph(
     const std::vector<std::set<int>>& visibility);
 
 }  // namespace internal
diff --git a/internal/ceres/visibility_based_preconditioner.cc b/internal/ceres/visibility_based_preconditioner.cc
index ed4afb6..0cf4afa 100644
--- a/internal/ceres/visibility_based_preconditioner.cc
+++ b/internal/ceres/visibility_based_preconditioner.cc
@@ -65,9 +65,9 @@
 //
 // This will require some more work on the clustering algorithm and
 // possibly some more refactoring of the code.
-static const double kCanonicalViewsSizePenaltyWeight = 3.0;
-static const double kCanonicalViewsSimilarityPenaltyWeight = 0.0;
-static const double kSingleLinkageMinSimilarity = 0.9;
+static constexpr double kCanonicalViewsSizePenaltyWeight = 3.0;
+static constexpr double kCanonicalViewsSimilarityPenaltyWeight = 0.0;
+static constexpr double kSingleLinkageMinSimilarity = 0.9;
 
 VisibilityBasedPreconditioner::VisibilityBasedPreconditioner(
     const CompressedRowBlockStructure& bs,
@@ -144,11 +144,11 @@
 }
 
 // Determine the sparsity structure of the CLUSTER_TRIDIAGONAL
-// preconditioner. It clusters cameras using using the scene
-// visibility and then finds the strongly interacting pairs of
-// clusters by constructing another graph with the clusters as
-// vertices and approximating it with a degree-2 maximum spanning
-// forest. The set of edges in this forest are the cluster pairs.
+// preconditioner. It clusters cameras using the scene visibility and
+// then finds the strongly interacting pairs of clusters by
+// constructing another graph with the clusters as vertices and
+// approximating it with a degree-2 maximum spanning forest. The set
+// of edges in this forest are the cluster pairs.
 void VisibilityBasedPreconditioner::ComputeClusterTridiagonalSparsity(
     const CompressedRowBlockStructure& bs) {
   vector<set<int>> visibility;
@@ -185,7 +185,7 @@
 // The cluster_membership_ vector is updated to indicate cluster
 // memberships for each camera block.
 void VisibilityBasedPreconditioner::ClusterCameras(
-    const vector<set<int> >& visibility) {
+    const vector<set<int>>& visibility) {
   std::unique_ptr<WeightedGraph<int>> schur_complement_graph(
       CreateSchurComplementGraph(visibility));
   CHECK(schur_complement_graph != nullptr);
@@ -342,7 +342,8 @@
   CHECK_GT(num_rows, 0);
 
   // Compute a subset of the entries of the Schur complement.
-  eliminator_->Eliminate(&A, nullptr, D, m_.get(), nullptr);
+  eliminator_->Eliminate(
+      BlockSparseMatrixData(A), nullptr, D, m_.get(), nullptr);
 
   // Try factorizing the matrix. For CLUSTER_JACOBI, this should
   // always succeed modulo some numerical/conditioning problems. For
@@ -464,7 +465,7 @@
 // each vertex.
 void VisibilityBasedPreconditioner::ForestToClusterPairs(
     const WeightedGraph<int>& forest,
-    std::unordered_set<pair<int, int>, pair_hash >* cluster_pairs) const {
+    std::unordered_set<pair<int, int>, pair_hash>* cluster_pairs) const {
   CHECK(cluster_pairs != nullptr);
   cluster_pairs->clear();
   const std::unordered_set<int>& vertices = forest.vertices();
diff --git a/internal/ceres/visibility_based_preconditioner.h b/internal/ceres/visibility_based_preconditioner.h
index 31ba171..0457b9a 100644
--- a/internal/ceres/visibility_based_preconditioner.h
+++ b/internal/ceres/visibility_based_preconditioner.h
@@ -140,13 +140,13 @@
   virtual ~VisibilityBasedPreconditioner();
 
   // Preconditioner interface
-  virtual void RightMultiply(const double* x, double* y) const;
-  virtual int num_rows() const;
+  void RightMultiply(const double* x, double* y) const final;
+  int num_rows() const final;
 
   friend class VisibilityBasedPreconditionerTest;
 
  private:
-  virtual bool UpdateImpl(const BlockSparseMatrix& A, const double* D);
+  bool UpdateImpl(const BlockSparseMatrix& A, const double* D) final;
   void ComputeClusterJacobiSparsity(const CompressedRowBlockStructure& bs);
   void ComputeClusterTridiagonalSparsity(const CompressedRowBlockStructure& bs);
   void InitStorage(const CompressedRowBlockStructure& bs);
@@ -162,8 +162,9 @@
       std::vector<std::set<int>>* cluster_visibility) const;
   WeightedGraph<int>* CreateClusterGraph(
       const std::vector<std::set<int>>& visibility) const;
-  void ForestToClusterPairs(const WeightedGraph<int>& forest,
-                            std::unordered_set<std::pair<int, int>, pair_hash>* cluster_pairs) const;
+  void ForestToClusterPairs(
+      const WeightedGraph<int>& forest,
+      std::unordered_set<std::pair<int, int>, pair_hash>* cluster_pairs) const;
   void ComputeBlockPairsInPreconditioner(const CompressedRowBlockStructure& bs);
   bool IsBlockPairInPreconditioner(int block1, int block2) const;
   bool IsBlockPairOffDiagonal(int block1, int block2) const;
diff --git a/internal/ceres/visibility_based_preconditioner_test.cc b/internal/ceres/visibility_based_preconditioner_test.cc
index a006d98..10aa619 100644
--- a/internal/ceres/visibility_based_preconditioner_test.cc
+++ b/internal/ceres/visibility_based_preconditioner_test.cc
@@ -31,6 +31,7 @@
 #include "ceres/visibility_based_preconditioner.h"
 
 #include <memory>
+
 #include "Eigen/Dense"
 #include "ceres/block_random_access_dense_matrix.h"
 #include "ceres/block_random_access_sparse_matrix.h"
diff --git a/internal/ceres/visibility_test.cc b/internal/ceres/visibility_test.cc
index 5028e01..a199963 100644
--- a/internal/ceres/visibility_test.cc
+++ b/internal/ceres/visibility_test.cc
@@ -46,8 +46,7 @@
 using std::set;
 using std::vector;
 
-class VisibilityTest : public ::testing::Test {
-};
+class VisibilityTest : public ::testing::Test {};
 
 TEST(VisibilityTest, SimpleMatrix) {
   //   A = [1 0 0 0 0 1
@@ -100,14 +99,15 @@
   }
   bs.cols.resize(num_cols);
 
-  vector< set<int>> visibility;
+  vector<set<int>> visibility;
   ComputeVisibility(bs, num_eliminate_blocks, &visibility);
   ASSERT_EQ(visibility.size(), num_cols - num_eliminate_blocks);
   for (int i = 0; i < visibility.size(); ++i) {
     ASSERT_EQ(visibility[i].size(), 1);
   }
 
-  std::unique_ptr<WeightedGraph<int> > graph(CreateSchurComplementGraph(visibility));
+  std::unique_ptr<WeightedGraph<int>> graph(
+      CreateSchurComplementGraph(visibility));
   EXPECT_EQ(graph->vertices().size(), visibility.size());
   for (int i = 0; i < visibility.size(); ++i) {
     EXPECT_EQ(graph->VertexWeight(i), 1.0);
@@ -121,14 +121,12 @@
       }
 
       EXPECT_EQ(graph->EdgeWeight(i, j), edge_weight)
-          << "Edge: " << i << " " << j
-          << " weight: " << graph->EdgeWeight(i, j)
+          << "Edge: " << i << " " << j << " weight: " << graph->EdgeWeight(i, j)
           << " expected weight: " << edge_weight;
     }
   }
 }
 
-
 TEST(VisibilityTest, NoEBlocks) {
   //   A = [1 0 0 0 0 0
   //        1 0 0 0 0 0
@@ -183,8 +181,8 @@
     ASSERT_EQ(visibility[i].size(), 0);
   }
 
-  std::unique_ptr<WeightedGraph<int> > graph(
-					     CreateSchurComplementGraph(visibility));
+  std::unique_ptr<WeightedGraph<int>> graph(
+      CreateSchurComplementGraph(visibility));
   EXPECT_EQ(graph->vertices().size(), visibility.size());
   for (int i = 0; i < visibility.size(); ++i) {
     EXPECT_EQ(graph->VertexWeight(i), 1.0);
@@ -197,8 +195,7 @@
         edge_weight = 1.0;
       }
       EXPECT_EQ(graph->EdgeWeight(i, j), edge_weight)
-          << "Edge: " << i << " " << j
-          << " weight: " << graph->EdgeWeight(i, j)
+          << "Edge: " << i << " " << j << " weight: " << graph->EdgeWeight(i, j)
           << " expected weight: " << edge_weight;
     }
   }
diff --git a/internal/ceres/wall_time.cc b/internal/ceres/wall_time.cc
index 09e3c4a..7163927 100644
--- a/internal/ceres/wall_time.cc
+++ b/internal/ceres/wall_time.cc
@@ -64,20 +64,24 @@
 #endif
 }
 
-EventLogger::EventLogger(const std::string& logger_name)
-    : start_time_(WallTimeInSeconds()),
-      last_event_time_(start_time_),
-      events_("") {
-  StringAppendF(&events_,
-                "\n%s\n                                   Delta   Cumulative\n",
-                logger_name.c_str());
+EventLogger::EventLogger(const std::string& logger_name) {
+  if (!VLOG_IS_ON(3)) {
+    return;
+  }
+
+  start_time_ = WallTimeInSeconds();
+  last_event_time_ = start_time_;
+  events_ = StringPrintf(
+      "\n%s\n                                   Delta   Cumulative\n",
+      logger_name.c_str());
 }
 
 EventLogger::~EventLogger() {
-  if (VLOG_IS_ON(3)) {
-    AddEvent("Total");
-    VLOG(2) << "\n" << events_ << "\n";
+  if (!VLOG_IS_ON(3)) {
+    return;
   }
+  AddEvent("Total");
+  VLOG(3) << "\n" << events_ << "\n";
 }
 
 void EventLogger::AddEvent(const std::string& event_name) {
diff --git a/internal/ceres/wall_time.h b/internal/ceres/wall_time.h
index 966aa67..9c92e9e 100644
--- a/internal/ceres/wall_time.h
+++ b/internal/ceres/wall_time.h
@@ -33,6 +33,7 @@
 
 #include <map>
 #include <string>
+
 #include "ceres/internal/port.h"
 #include "ceres/stringprintf.h"
 #include "glog/logging.h"
@@ -44,7 +45,7 @@
 // OpenMP is available then the high precision openmp_get_wtime()
 // function is used. Otherwise on unixes, gettimeofday is used. The
 // granularity is in seconds on windows systems.
-double WallTimeInSeconds();
+CERES_EXPORT_INTERNAL double WallTimeInSeconds();
 
 // Log a series of events, recording for each event the time elapsed
 // since the last event and since the creation of the object.
@@ -77,7 +78,7 @@
   void AddEvent(const std::string& event_name);
 
  private:
-  const double start_time_;
+  double start_time_;
   double last_event_time_;
   std::string events_;
 };